在设计五中,我们把事件系统EventSystem实现一下。这个EventSystem类主要实现的是事件的注册,触发,以及分发Event消息的作用。提供接口对外使用的。在这里面为了功能扩展方便用了好多模板函数,方便大家调用。
分发消息的时候,我们采用的是队列的方式,就是先进先出原则。
首先要把消息事件注册一下,就是将其放到我们预先定义的表里面。函数代码如下所示:
int Register(string eventName, Func<object,object,object,bool> action) { int listenID = ++mNextListenID; Listen listen = (mFreeListen.Count == 0) ? new Listen() : mFreeListen.Pop(); listen.mID = listenID; listen.mAction = action; mRegistered.Add(listenID, listen); List<int> eventList; if(!mRegisteredEvents.TryGetValue(eventName, out eventList)) eventList = mRegisteredEvents[eventName] = new List<int>(); eventList.Add(listenID); return listenID; }
接下来就是 消息事件的触发代码如下:
public void Trigger(string eventName) { Call(eventName, null, null, null); }
void Call(string eventName, object arg1, object arg2, object arg3) { List<int> listenerList; if(mRegisteredEvents.TryGetValue(eventName, out listenerList)) { for(int i = listenerList.Count - 1; i >= 0; --i) { Listen listener; if(mRegistered.TryGetValue(listenerList[i], out listener)) { if(!listener.mAction(arg1, arg2, arg3)) { mRegistered.Remove(listenerList[i]); mFreeListen.Push(listener); listenerList.RemoveAt(i); } } else { listenerList.RemoveAt(i); } } if(listenerList.Count == 0) { mRegisteredEvents.Remove(eventName); } } }
遍历查找消息列表是否在mRegistererdEvents这个字典里面,mRegisteredEvents的定义如下:
Dictionary<string,List<int>> mRegisteredEvents = new Dictionary<string, List<int>>();
Listen的定义如下:
class Listen { public int mID; public Func<object,object,object,bool> mAction; }
接下来就是最核心的功能了,状态机的切换功能代码:
public int On<T1,T2,T3>(string eventName, Func<T1,T2,T3,bool> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; T3 param3; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } try { param3 = (T3)arg3; } catch { param3 = default(T3); } return(action(param1, param2, param3)); }); } public int On<T1,T2,T3>(string eventName, Action<T1,T2,T3> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; T3 param3; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } try { param3 = (T3)arg3; } catch { param3 = default(T3); } action(param1, param2, param3); return true; }); }
整个的EventSystem事件系统的代码如下所示:
using System; using System.Collections; using System.Collections.Generic; namespace EventSystem { public class Dispatcher { public void Trigger(string eventName) { Call(eventName, null, null, null); } public void Dispatch(string eventName) { Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop(); mDispatched.Enqueue(d.Set(eventName)); } public int On(string eventName, Func<bool> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { return(action()); }); } public int On(string eventName, Action action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { action(); return(true); }); } public void Trigger(string eventName, object param1) { Call(eventName, param1, null, null); } public void Dispatch(string eventName, object param1) { Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop(); mDispatched.Enqueue(d.Set(eventName, param1)); } public int On<T>(string eventName, Func<T,bool> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T param1; try { param1 = (T)arg1; } catch { param1 = default(T); } return(action(param1)); }); } public int On<T>(string eventName, Action<T> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T param1; try { param1 = (T)arg1; } catch { param1 = default(T); } action(param1); return true; }); } public void Trigger(string eventName, object param1, object param2) { Call(eventName, param1, param2, null); } public void Dispatch(string eventName, object param1, object param2) { Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop(); mDispatched.Enqueue(d.Set(eventName, param1, param2)); } public int On<T1,T2>(string eventName, Func<T1,T2,bool> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } return(action(param1, param2)); }); } public int On<T1,T2>(string eventName, Action<T1,T2> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } action(param1, param2); return true; }); } public void Trigger(string eventName, object param1, object param2, object param3) { Call(eventName, param1, param2, param3); } public void Dispatch(string eventName, object param1, object param2, object param3){ Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop(); mDispatched.Enqueue(d.Set(eventName, param1, param2, param3)); } public int On<T1,T2,T3>(string eventName, Func<T1,T2,T3,bool> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; T3 param3; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } try { param3 = (T3)arg3; } catch { param3 = default(T3); } return(action(param1, param2, param3)); }); } public int On<T1,T2,T3>(string eventName, Action<T1,T2,T3> action) { return Register(eventName, delegate(object arg1, object arg2, object arg3) { T1 param1; T2 param2; T3 param3; try { param1 = (T1)arg1; } catch { param1 = default(T1); } try { param2 = (T2)arg2; } catch { param2 = default(T2); } try { param3 = (T3)arg3; } catch { param3 = default(T3); } action(param1, param2, param3); return true; }); } public bool Cancel(int listenerID) { return mRegistered.Remove(listenerID); } public void DispatchPending() { while(mDispatched.Count > 0) { Dispatched d = mDispatched.Dequeue(); Call(d.mEventName, d.mArg1, d.mArg2, d.mArg3); mFreeDispatch.Push(d); } } int Register(string eventName, Func<object,object,object,bool> action) { int listenID = ++mNextListenID; Listen listen = (mFreeListen.Count == 0) ? new Listen() : mFreeListen.Pop(); listen.mID = listenID; listen.mAction = action; mRegistered.Add(listenID, listen); List<int> eventList; if(!mRegisteredEvents.TryGetValue(eventName, out eventList)) eventList = mRegisteredEvents[eventName] = new List<int>(); eventList.Add(listenID); return listenID; } void Call(string eventName, object arg1, object arg2, object arg3) { List<int> listenerList; if(mRegisteredEvents.TryGetValue(eventName, out listenerList)) { for(int i = listenerList.Count - 1; i >= 0; --i) { Listen listener; if(mRegistered.TryGetValue(listenerList[i], out listener)) { if(!listener.mAction(arg1, arg2, arg3)) { mRegistered.Remove(listenerList[i]); mFreeListen.Push(listener); listenerList.RemoveAt(i); } } else { listenerList.RemoveAt(i); } } if(listenerList.Count == 0) { mRegisteredEvents.Remove(eventName); } } } class Listen { public int mID; public Func<object,object,object,bool> mAction; } class Dispatched { public Dispatched Set(string eventName, object arg1=null, object arg2=null, object arg3=null) { mEventName = eventName; mArg1 = arg1; mArg2 = arg2; mArg3 = arg3; return this; } public string mEventName; public object mArg1, mArg2, mArg3; } Dictionary<string,List<int>> mRegisteredEvents = new Dictionary<string, List<int>>(); Dictionary<int,Listen> mRegistered = new Dictionary<int, Listen>(); Stack<Listen> mFreeListen = new Stack<Listen>(); Stack<Dispatched> mFreeDispatch = new Stack<Dispatched>(); Queue<Dispatched> mDispatched = new Queue<Dispatched>(); int mNextListenID = 4711; } }
接下来我会在最后一讲也就是设计六中,给大家说一下如何去使用。
本文出自 “海游移动” 博客,请务必保留此出处http://jxwgame.blog.51cto.com/943299/1613585
原文地址:http://jxwgame.blog.51cto.com/943299/1613585