Unity简易事件系统
事件系统是一个基于观察者模式之上构建的系统。通过利用delegate来进行Multicasting,实现一处激发则一触全发。
以下代码以简单的形式实现了一个仅限void类型函数的事件系统。
public class EventManager : MonoSingleton<EventManager>
{
private static Dictionary<string, Action> dic = new Dictionary<string, Action>();
public static void AddEvt(string tag, Action subscribe)
{
if(dic.ContainsKey(tag))
dic[tag] += subscribe;
else
dic.Add(tag, subscribe);
}
public static void DeleteEvt(string tag)
{
if(!dic.ContainsKey(tag))
throw new Exception("Tag \"" + tag + "\" not found in the list");
dic.Remove(tag);
}
public static void CancelSubscribe(string tag, Action subscribe)
{
if(!dic.ContainsKey(tag))
throw new Exception("Event \"" + tag + "\" not found in the list.");
dic[tag] -= subscribe;
}
public static void invokeEvt(string tag)
{
if(!dic.ContainsKey(tag))
throw new Exception("Event \"" + tag + "\" not found in the list.");
dic[tag]();
}
public static void AllClear()
{
dic.Clear();
}
}
一、为什么以string
为关键词,而没用Enum
实际上两者都可以,但是我喜欢string
,并且以string
为关键词时拓展起来也比较方便。当然,缺点也很显而易见,如果事件数量逐渐增多,那么string
的内容必须要做好管理,并且得保证不重名&没有错字。如果是enum
则不会有这个问题。但是我就是喜欢string
二、思路
首先,新建一个Dictionary
。
public static void AddEvt(string tag, Action subscribe)
用string
来作为关键词(事件名字)来查找对应的Action
,如果对应事件不存在,那就建立,如果已经存在了,那就只给对应Action继续添加内容。
public static void DeleteEvt(string tag)
查找对应的tag,如果不存在那就及时抛出错误。如果存在,那就直接把整个事件全删了。
public static void CancelSubscribe(string tag, Action subscribe)
仅去除其中一个关注者。
public static void invokeEvt(string tag)
调用对应事件。
public static void AllClear()
事件全删了,一个不留。
备注:
Action
Action
的本质就是一层简单封装过的delegate
,没有任何后续描述时,Action
则作为无传入任何参数的void函数,没有返回值。如需要返回值,则可去参考Func
MonoSingleton<T>
详见单例篇,此处借用单例系统来单例化事件管理者。根据实际需要,也不一定要将管理者作为单例处理,也可以考虑直接以此为一个基类拓展出不同的事件管理者。