美文网首页
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事件系统新设计

    之前设计过一版事件系统,使用params object[]来做参数的传递,后发现这么设计会有问题,因为不同的接收对...

  • Unity事件系统

    Unity的事件系统可以概述为4个部分:EventSystem、BaseInputModule(包括其子类)、Ba...

  • Unity UGUI系列十 EventSystem 和Input

    一、Event System 参考【Unity学习笔记】事件系统EventSystem[https://blog....

  • 「Unity3D」(3)事件系统和EventSystem详细解读

    Unity的事件系统提供了多种使用方式,又和物理碰撞结合在一起,所以同样使用Unity事件处理,就能写出各种各样的...

  • 2020-10-23 Unity事件系统设计

    我们项目框架设计中事件系统是必不可少的,便于我们各个模块之间方便通讯,这大大的降低了我们的耦合度,也增加了代码的可...

  • Unity 新 InputSystem 的简要使用

    本文转自Unity Connect博主 冻葱Tewi 有关 Unity 新输入系统 Input System 的一...

  • 对Unity的观察

    1,事件系统 为了高效起见,Unity的事件系统是用反射来触发的。 为何这能高效? 因为如果用反射,而你一开始没有...

  • Unity背包系统设计

    背包系统设计思路 基本思路:玩家在场景中捡到东西——放入背包中对应Item栏——点击装备武器放入人物装备槽(改变s...

  • 【Unity】Unity 5.0 新布料系统

    这一章讲一下布料系统, 这次的布料系统有很大的改良. Unity4中, 需要对SkinnedMeshRendere...

  • Unity基础(14)-事件系统

    一、生命周期 1、生命周期函数 废话不说直接代码演示 运行结果 2、各个生命周期函数的作用 1.Awake:用于在...

网友评论

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

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