小球大作战-事件分发器
提供了2种EventDispatcher ,一种是用hash table 来存储 string 类型的key
一种是同数组 ,和const int事件类型 来存储 实现比hash还快的 索引
完整代码
using UnityEngine; using System.Collections; using System; using System.Collections.Generic; // this is custom event (use string0 public class EventDispatcher : ZT_Object { private EventDispatcher() { EventSystem.ins.AddEvent_Update(this); } Hashtable objs = new Hashtable(); Hashtable objs_for_once = new Hashtable(); public static EventDispatcher ins { get { return EventDispatcher.GetInstance(); } } private static EventDispatcher _ins = null; public static EventDispatcher GetInstance() { if (_ins == null) { _ins = new EventDispatcher(); } return _ins; } public static void DestroyInstance() { _ins.Clear(); _ins = null; } public static EventDispatcher Create(string name = "UnName") { EventDispatcher ret = new EventDispatcher(); ret.name = name; return ret; } public void PostEvent(string type, object userdata = null) { if (objs.ContainsKey(type)) { ArrayList list = objs[type] as ArrayList; for( int i=0;i<list.Count;i++ ) { ZT_Object obj = list[i] as ZT_Object; obj.OnEvent(type, userdata); } } } public void PostEventOnce(string type, object userdata = null) { //call for once if (objs_for_once.ContainsKey(type)) { ArrayList list = objs_for_once[type] as ArrayList; foreach (ZT_Object obj in list) { obj.OnEvent(type, userdata); } objs_for_once.Remove(type); } } public void AddEventListener(ZT_Object target, string type) { if (objs.ContainsKey(type) == false) { objs.Add(type, new ArrayList()); } ArrayList list = objs[type] as ArrayList; list.Add(target); } public void RemoveEventListener(ZT_Object target, string type) { if (objs.ContainsKey(type) == false) { return; } ArrayList list = objs[type] as ArrayList; list.Remove(target); } public void Clear() { objs.Clear(); } public void AddEventListenerOnce(ZT_Object target, string type) { if (objs_for_once.ContainsKey(type) == false) { objs_for_once.Add(type, new ArrayList()); } ArrayList list = objs_for_once[type] as ArrayList; list.Add(target); } public void AddFuncToMainThread(Func<int> func) { this._queue_funcs.Enqueue(func); } private void ProcessOtherThreadFunc() { _queue_funcs.Lock(); while (_queue_funcs.UnSafeEmpty() == false) { Func<int> func = _queue_funcs.UnSafeDequeue() as Func<int>; func(); } _queue_funcs.UnLock(); } public override void Update() { this.ProcessOtherThreadFunc(); } private ThreadSafeQueue _queue_funcs = new ThreadSafeQueue(); public string name = "Global"; }; //this is event which used int for Event public class ZTEventDispatcher : object { private ZTEventDispatcher() { for (int i = 0; i < Event.MAX_EVENT_LENGTH; i++) { objs.Add(null); objs_for_once.Add(null); } } ArrayList objs = new ArrayList(); ArrayList objs_for_once = new ArrayList(); public static ZTEventDispatcher ins { get { return ZTEventDispatcher.GetInstance(); } } private static ZTEventDispatcher _ins = null; public static ZTEventDispatcher GetInstance() { if (_ins == null) { _ins = new ZTEventDispatcher(); } return _ins; } public static void DestroyInstance() { _ins.Clear(); _ins = null; } public static ZTEventDispatcher Create(string name = "UnName") { ZTEventDispatcher ret = new ZTEventDispatcher(); ret.name = name; return ret; } public void PostEvent(int type, object userdata = null) { if (objs[type] == null) { return; } ArrayList list = objs[type] as ArrayList; foreach (ZT_Object obj in list) { obj.OnEvent(type, userdata); } } public void PostEventOnce(int type, object userdata = null) { //call for once if (objs_for_once[type] != null) { ArrayList list = objs_for_once[type] as ArrayList; foreach (ZT_Object obj in list) { obj.OnEvent(type, userdata); } objs_for_once.Remove(type); } } public void AddEventListener(ZT_Object target, int type) { if (objs[type] == null) { objs[type] = new ArrayList(); } ArrayList list = objs[type] as ArrayList; list.Add(target); } public void RemoveEventListener(ZT_Object target, int type) { if (objs[type] == null) { return; } ArrayList list = objs[type] as ArrayList; list.Remove(target); } public void Clear() { objs.Clear(); } public void AddEventListenerOnce(ZT_Object target, int type) { if (objs_for_once[type] == null) { objs_for_once[type] = new ArrayList(); } ArrayList list = objs_for_once[type] as ArrayList; list.Add(target); } public string name = "GlobalZTEvent"; }; ZT_Object using UnityEngine; using System.Collections; using System; public class ZT_Object : IDisposable { // every frame will be call public virtual void Update() { } //every logic frame will be call(Frame Sync to All clients) public virtual void UpdateMS() { } //use this to init you class public virtual bool Init() { return true; } public virtual void OnEvent(string type, object userData) { } public virtual void OnEvent(int type, object userData) { } // you can override this interface to release your Res ,Rem. must call base.OnExit when you override public virtual void OnExit() { } // you can use this interface to notify class to release//OnExit will be call // use this or Release() public void Dispose() { this.OnExit(); } // use this or Dispose() public void Release() { this.Dispose(); } };
此外ZT_Object为客户端所有对象的父类,负责消息派发,事件响应,逻辑更新接口,每帧更新接口,析构处理等。
EventDispatcher 在主线程跑,提供了其他线程添加主线程执行函数 回调方法