C#_简易消息机制

发布于 2020-05-18  26 次阅读


前言

消息机制会一直要用到,也有多重写法,基本上就是订阅,取订,通知。

字符串消息体

 public static class MsgDispatcher
    {
        private static Dictionary<string, Action<object>> RegisteredMsgs = new Dictionary<string, Action<object>>();

        public static void Register( string msgName, Action<object> onMsgReceived)
        {
            RegisteredMsgs.Add(msgName, onMsgReceived);
        }

        public static void UnRegister( string msgName)
        {
            RegisteredMsgs.Remove(msgName);
        }
        public static void SendMsg( string msgName, object data)
        {
            RegisteredMsgs[msgName](data);
        }

        private static void MenuClicked()
        {
            //Register("消息1", data => { Debug.LogFormat("消息1:{0}", data); });

            //Send("消息1", "hello world");

            //UnRegister("消息1");

            //Send("消息1", "hello");
        } 
    }

基于类型的消息事件

public class TypeEventSystem
{
    // 接口 只负责存储在字典中
    interface IRegisterations
    {

    }
    // 多个注册
    class Registerations : IRegisterations
    {
        // 不需要 List> 了 因为委托本身就可以一对多注册
        public Action OnReceives = obj => { };
    }

   private static Dictionary< Type, IRegisterations > mTypeEventDict = new Dictionary();

    // 注册事件
    public static void Register(System.Action onReceive)
    {
        var type = typeof(T);
        IRegisterations registerations = null;
        if (mTypeEventDict.TryGetValue(type, out registerations))
        {
            var reg = registerations as Registerations;
            reg.OnReceives += onReceive;
        }
        else
        {
            var reg = new Registerations();
            reg.OnReceives += onReceive;
            mTypeEventDict.Add(type, reg);
        }
    }

    // 注销事件
    public static void UnRegister(System.Action onReceive)
    {
        var type = typeof(T);
        IRegisterations registerations = null;
        if (mTypeEventDict.TryGetValue(type, out registerations))
        {
            var reg = registerations as Registerations;
            reg.OnReceives -= onReceive;
        }
    }

    // 发送事件
    public static void Send(T t)
    {
        var type = typeof(T);

        IRegisterations registerations = null;

        if (mTypeEventDict.TryGetValue(type, out registerations))
        {
            var reg = registerations as Registerations;
            reg.OnReceives(t);
        }
    }

    // 发送事件
    public static void Send() where T : new()
    {
        var type = typeof(T);

        IRegisterations registerations = null;

        if (mTypeEventDict.TryGetValue(type, out registerations))
        {
            var reg = registerations as Registerations;
            reg.OnReceives(new T());
        }
    }
}

Example

public class GameStartEvent
{
}
public class GameOverEvent
{
    // 可以携带参数
    public int Score;
}
public class TypeEventSystemExample : MonoBehaviour
{
    private void Start()
    {
        TypeEventSystem.Register<GameStartEvent>(OnGameStartEvent);
        TypeEventSystem.Register<GameOverEvent>(OnGameOverEvent);

        TypeEventSystem.Send<GameStartEvent>();
        TypeEventSystem.Send(new GameOverEvent()
                             {
                                 Score = 100
                             });
    }

    private void OnGameOverEvent(GameOverEvent obj)
    {
        Debug.Log("分数" + obj.Score);
    }
    private void OnGameStartEvent(GameStartEvent obj)
    {
        Debug.Log("Start");
    }
    private void OnDestroy()
    {
        TypeEventSystem.UnRegister<GameStartEvent>(OnGameStartEvent);
        TypeEventSystem.UnRegister<GameOverEvent>(OnGameOverEvent);
    }
}

基于枚举(int)的消息机制

namespace SQFramework
{
    public delegate void EventMgr(params object[] param);
    public interface IEventMgr
    {
        void Register(int key, EventMgr eventMgr);//注册事件 
        void UnRegister(int key);//解绑事件 
        void ClearAll();//解绑所有事件 
        bool IsRegisterName(int key);//key值是否被注册 
        bool IsRegisterFunc(EventMgr eventMgr);//eventMgr是否被注册 
        void Invoke(int key, params object[] param);//调用
    }
    public class EventManager :Singleton<EventManager>, IEventMgr
    {
        // 存储注册好的事件
        protected readonly Dictionary<int, EventMgr> EventListerDict = new Dictionary<int, EventMgr>();

        // 是否暂停所有的事件
        public bool IsPause = false;

        // 注册事件
        public void Register(int key, EventMgr eventMgr)
        {
            if (EventListerDict.ContainsKey(key))
            {
                Debug.LogError("Key:" + key + "已存在!");
            }
            else
            {
                EventListerDict.Add(key, eventMgr);
            }
        }

        // 取消事件绑定
        public void UnRegister(int key)
        {
            if (EventListerDict != null && EventListerDict.ContainsKey(key))
            {
                EventListerDict.Remove(key);
                Debug.Log("移除事件:" + key);
            }
            else
            {
                Debug.LogError("Key:" + key + "不存在!");
            }
        }

        // 取消所有事件绑定
        public void ClearAll()
        {
            if (EventListerDict != null)
            {
                EventListerDict.Clear();
                Debug.Log("清空注册事件!");
            }
        }

        // ID是否注册过
        public bool IsRegisterName(int key)
        {
            if (EventListerDict != null && EventListerDict.ContainsKey(key))
            {
                EventListerDict.Remove(key);
                Debug.Log("事件:" + key + "已注册!");
                return true;
            }
            Debug.Log("事件:" + key + "未注册!");
            return false;
        }
        // 方法是否注册过
        public bool IsRegisterFunc(EventMgr eventMgr)
        {
            if (EventListerDict != null && EventListerDict.ContainsValue(eventMgr))
            {
                Debug.Log("事件已注册!");
                return true;
            }
            Debug.Log("事件未注册!");
            return false;
        }

        // 调用事件 
        public void SendEvent(int key, params object[] param)
        {
            if (!IsPause)
            {
                if (EventListerDict.ContainsKey(key))
                {
                    EventListerDict[key].Invoke(param);
                }
                else
                {
                    Debug.LogError("事件:" + key + "未注册!");
                }
            }
            else
            {
                Debug.LogError("所有事件已暂停!");
            } 
        }
    } 
      public enum EventQ
    {
        Start = 0,
        One = 1,
        Two =2,
        End = 3,
    }
    public class EnmuEventExample : MonoBehaviour
    {
        private void Start()
        {
            EventManager.Instance.Register((int)EventQ.One, ddd);
            EventManager.Instance.SendEvent((int)EventQ.One,"123",12); 
        }

        private void ddd(object[] param)
        {
            Debug.Log(param.Length);
        } 
    }
}

不积跬步,无以至千里;不积小流,无以成江海。