美文网首页
2020-11-02 Unity事件系统新设计

2020-11-02 Unity事件系统新设计

作者: VECTOR_Y | 来源:发表于2020-11-03 11:00 被阅读0次

    之前设计过一版事件系统,使用params object[]来做参数的传递,后发现这么设计会有问题,因为不同的接收对象所需要的参数可能是不同的,所以重新设计了一版

    /// <summary>
    /// 事件基类
    /// </summary>
    public class EventHandler
    {
        public delegate void _HandleEvent(EventDef ev, LogicEvent le);
    
        private _HandleEvent mhandler = null;
    
        public void RegisterEvent(EventDef ev)
        {
            EventMgrHelper.Ins.RegisterEventHandler(ev, this);
        }
    
        public void UnRegisterEvent(EventDef ev)
        {
            EventMgrHelper.Ins.UnRegisterEventHandler(ev, this);
        }
    
        public virtual void HandleEvent(EventDef ev, LogicEvent le)
        {
                mhandler?.Invoke(ev, le);
        }
    
        public _HandleEvent Handler
        {
            set { mhandler = value; }
        }
    }
    
    using System.Collections.Generic;
    
    /// <summary>
    /// 事件参数对象
    /// </summary>
    public class LogicEvent
    {
        public const string NUMBER_MIN_STR = "MIN";
        public const string NUMBER_MAX_STR = "MAX";
        public const string NUMBER_DEFAULT_STR = "DEFAULT";
        private EventDef mEvent = EventDef.NONE;
        private int mIntParam0 = -1;
        private int mIntParam1 = -1;
        private float mFloatParam0 = -1;
        private float mFloatParam1 = -1;
        private string mStrParam0 = "";
        private string mStrParam1 = "";
        private System.Object mObject0;
        private System.Object mObject1;
        private bool mLocked = false;
        private Dictionary<string, int> mDicParam0 = new Dictionary<string, int>();
    
        static MemoryPool<LogicEvent> msEventPool = new MemoryPool<LogicEvent>(50);
    
        public static int mDebugCount = 0;
    
        public LogicEvent()
        {
            ++mDebugCount;
        }
    
        private void Reset()
        {
            mEvent = EventDef.NONE;
            mIntParam0 = -1;
            mIntParam1 = -1;
            mFloatParam0 = -1;
            mFloatParam1 = -1;
            mStrParam0 = "";
            mStrParam1 = "";
            mObject0 = null;
            mObject1 = null;
            mDicParam0.Clear();
        }
    
        static public LogicEvent CreateEvent()
        {
            LogicEvent le = msEventPool.Alloc();
            if (le != null)
            {
                return le;
            }
    
            return new LogicEvent();
        }
    
        static public void DestroyEvent(LogicEvent le)
        {
            le.Reset();
            msEventPool.Free(le);
        }
    
        ~LogicEvent()
        {
            --mDebugCount;
        }
    
        public EventDef Event
        {
            set { mEvent = value; }
            get { return mEvent; }
        }
    
        public bool Locked
        {
            set { mLocked = value; }
            get { return mLocked; }
        }
    
        public int IntParam0
        {
            set { mIntParam0 = value; }
            get { return mIntParam0; }
        }
    
        public int IntParam1
        {
            set { mIntParam1 = value; }
            get { return mIntParam1; }
        }
    
        public float FloatParam0
        {
            set { mFloatParam0 = value; }
            get { return mFloatParam0; }
        }
        public float FloatParam1
        {
            set { mFloatParam1 = value; }
            get { return mFloatParam1; }
        }
    
        public string StrParam0
        {
            set { mStrParam0 = value; }
            get { return mStrParam0; }
        }
    
        public string StrParam1
        {
            set { mStrParam1 = value; }
            get { return mStrParam1; }
        }
    
        public System.Object Object0
        {
            set { mObject0 = value; }
            get { return mObject0; }
        }
    
        public System.Object Object1
        {
            set { mObject1 = value; }
            get { return mObject1; }
        }
    
        public Dictionary<string, int> DicParam0
        {
            set { mDicParam0 = value; }
            get { return mDicParam0; }
        }
    }
    
    
    using System.Collections.Generic;
    
    /// <summary>
    /// 对象池
    /// </summary>
    public class MemoryPool<T> where T : class
    {
        /**
        * @description 切勿单独操作此集合,如需增删请引用封装的函数
        * @description 此数组在此用作模拟队列来处理数据,遵循先进先出,所以请勿单独操作此数组
        */
        public int Count { get { return mobjs.Count; } }
        private Queue<T> mobjs = new Queue<T>();
        private int mMaxSize = 10;
    
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="maxSize">最大数量</param>
        public MemoryPool(int maxSize = 10)
        {
            mMaxSize = maxSize;
        }
    
        /// <summary>
        /// 出列
        /// </summary>
        public T Alloc()
        {
            T t = null;
            if (mobjs.Count > 0)
            {
                t = mobjs.Dequeue();
            }
            return t;
        }
            
        /// <summary>
        /// 入队
        /// </summary>
        public void Free(T t)
        {
            if (mobjs.Count < mMaxSize)
            {
                mobjs.Enqueue(t);
            }
        }
    
        /// <summary>
        /// 部署
        /// </summary>
        public void Dispose()
        {
            mobjs.Clear();
        }
    }
    
    using System;
    using System.Collections.Generic;
    
        /// <summary>
        /// 事件注册 分发
        /// </summary>
    public class EventMgrHelper : BaseClass<EventMgrHelper>
    {
        private Dictionary<EventDef, List<EventHandler>> mDicHandler = new Dictionary<EventDef, List<EventHandler>>();
    
        /// <summary>
        /// 注册事件
        /// </summary>
        public void RegisterEventHandler(EventDef ed, EventHandler handler)
        {
            List<EventHandler> lh;
            if (mDicHandler.TryGetValue(ed, out lh))
            {
                lh.Add(handler);
            }
            else
            {
                lh = new List<EventHandler>();
                lh.Add(handler);
    
                mDicHandler.Add(ed, lh);
            }
        }
    
        /// <summary>
        /// 解绑事件
        /// </summary>
        public void UnRegisterEventHandler(EventDef ed, EventHandler handler)
        {
            List<EventHandler> lh;
            if (mDicHandler.TryGetValue(ed, out lh))
            {
                for (int i = 0; i < lh.Count; ++i)
                {
                    if (lh[i] == handler)
                    {
                        lh.RemoveAt(i);
                        return;
                    }
                }
            }
        }
    
        private LogicEvent CreateLogicEvent()
        {
            return LogicEvent.CreateEvent();
        }
    
        public void PushEventWhenNotExist(EventDef ed)
        {
            if (!ExistEvent(ed))
                this.PushEvent(ed);
        }
    
        private bool ExistEvent(EventDef le)
        {
            List<EventHandler> events;
            if (mDicHandler.TryGetValue(le,out events)) 
            {
                return true;
            }
            return false;
        }
    
        public int GetCount()
        {
            return mDicHandler.Count;
        }
    
        // use EventMgrHelper.PushEvent instead
        public void PushEvent(EventDef ed, int intdata0 = -1, int intdata1 = -1, string strData0 = "", string strData1 = "", bool checkSameEvent = false, float floatdata0 = -1, float floatdata1 = -1)
        {
            if (checkSameEvent)
            {
                if (ExistEvent(ed))
                    return;
            }
            LogicEvent le = CreateLogicEvent();
            le.Event = ed;
            le.IntParam0 = intdata0;
            le.IntParam1 = intdata1;
            le.StrParam0 = strData0;
            le.StrParam1 = strData1;
            le.FloatParam0 = floatdata0;
            le.FloatParam1 = floatdata1;
    
            PushEvent(le);
        }
    
        // use EventMgrHelper.PushEvent instead
        public void PushEventEx(EventDef ed, System.Object object0, System.Object object1=null, int data0=-1, int data1=-1, string strData0="", string strData1="", bool checkSameEvent = false, float floatdata0 = -1, float floatdata1 = -1)
        {
            if (checkSameEvent)
            {
                if (ExistEvent(ed))
                    return;
            }
            LogicEvent le = CreateLogicEvent();
            le.Event = ed;
    
            le.Object0 = object0;
            le.Object1 = object1;
            le.IntParam0 = data0;
            le.IntParam1 = data1;
            le.StrParam0 = strData0;
            le.StrParam1 = strData1;
            le.FloatParam0 = floatdata0;
            le.FloatParam1 = floatdata1;
                
            PushEvent(le);
        }
    
    
        private void PushEvent(LogicEvent le)
        {
            List<EventHandler> lh;
            if (!mDicHandler.TryGetValue(le.Event, out lh))
            {
                string logText = "event = " + le.Event.ToString() + " not find Handler";
                UnityEngine.Debug.Log(logText);
                return;
            }
    
            for (int j = 0; j < lh.Count; ++j)
            {
                try  
                {
                    lh[j].HandleEvent(le.Event, le);
                }
                catch (System.Exception e)
                {
                    UnityEngine.Debug.Log(le.Event + " " + e.Message);
                }
    
                if (!le.Locked)
                {
                    LogicEvent.DestroyEvent(le);
                }
            }
        }
    }
    
    /// <summary>
    /// 事件key
    /// </summary>
    public enum EventDef
    {
        NONE = 0,
        Callback,//公用事件
    
        // -------------------------------------------------------分割线结束
        Max,//在这前面加
    }
    
    using UnityEngine;
    
    /// <summary>
    /// 事件接收示例,公用的事件接收
    /// </summary>
    public class GameEvent : EventHandler {
    
        public GameEvent()
        {
            //注册事件
            RegisterEvent(EventDef.Callback);
        }
    
        public override void HandleEvent(EventDef ev, LogicEvent le)
        {
            base.HandleEvent(ev, le);
            if (ev == EventDef.Callback)
            {
                Debug.Log("callback+:" + le.StrParam0.ToString());
            }
        }
    }
    
    //调用示例
    GameEvent gam = new GameEvent();
    EventMgrHelper.Ins.PushEvent(EventDef.Callback,strData0:"dddddddddddddddddddddddd");
    

    相关文章

      网友评论

          本文标题:2020-11-02 Unity事件系统新设计

          本文链接:https://www.haomeiwen.com/subject/hbkmvktx.html