小球大作战-事件分发器
提供了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 在主线程跑,提供了其他线程添加主线程执行函数 回调方法
