https://blog.csdn.net/qq_29579137/article/details/73717882


我们先讲解一下简单事件系统和PureMVC中的命令/通知系统做个比较。

1. 简单事件系统

事件系统是委托的典型用法,C#委托包含Action、delegate、Func、predicate几种类型,具体的用法可以去百度查阅一下其他资料,这里我们先简单讲解一下事件系统。事件系统在Unity中可以用来解耦视图与模型,使得视图和模型重用性都有所提升。Unity WIKI这里有很多变种的事件系统。

1.1 什么是事件系统

简单讲就是利用字典记录方法,执行事件系统就是调用已经记录的方法。

1.2 事件系统代码

以下是一个简易事件系统的模板:

public class EventSystem
{
    //事件字典
    private static readonly Dictionary<string , Delegate> Events = new Dictionary<string, Delegate>();

    //执行事件的重载方法
    public static void Invoke(string eventName)
    {
            foreach (Delegate @delegate in invoke(eventName))
                @delegate.DynamicInvoke();
    }
    public static void Invoke<T>(string eventName,T argt ){}

    //执行事件异常检查
    private static Delegate[] invoke( string eventName )
    {
        if (!Events.ContainsKey(eventName))
            UnityEngine.Debug.LogError(string.Format("Can not get the {0} event!",eventName));
        Delegate @delegate = Events[eventName];
        return @delegate.GetInvocationList();
    }

    //注册事件的重载方法
    public static void Register( string eventName, Action action )
    {
        register(eventName);
        Events[eventName] = (Action)Events[eventName] + action;
    }
    public static void Register<T>( string eventName , Action<T> action ){}

    //注册事件
    private static void register( string eventName )
    {
        if (!Events.ContainsKey(eventName))
            Events.Add(eventName, null);
    }

    //注销事件的重载方法
    public static void UnRegister( string eventName , Action action )
    {
        register(eventName);
        Events[eventName] = (Action)Events[eventName] - action;
    }

    //清楚事件的重载方法
    public static void Clear( string eventName )
    {
        if (Events.ContainsKey(eventName))
            Events[eventName] = null;
    }
}

1.3 事件系统案例

结合一个小的案例看一下简单的事件系统的使用:

internal class TestClass : MonoBehaviour
{
    public const string EVENT_NAME = "EventName";
    private void Awake()
    {
        TestEvent test = new TestEvent();
        //注册事件
        EventSystem.Register(EVENT_NAME,test.Invoke);
    }
}

internal class TestEvent
{
    public void Invoke()
    {
        Debug.Log("Invoke");
    }
}

internal class TestInvoker : MonoBehaviour
{
    public const string EVENT_NAME = "EventName";
    public void Start()
    {
        //执行事件,即可执行以及注册对应的事件
        SpringFramework.Event.EventSystem.Invoke(EVENT_NAME);
    }
}