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>

详见单例篇,此处借用单例系统来单例化事件管理者。根据实际需要,也不一定要将管理者作为单例处理,也可以考虑直接以此为一个基类拓展出不同的事件管理者。

posted @ 2024-02-19 18:19  ComputerEngine  阅读(59)  评论(0编辑  收藏  举报