Unity中简单粗暴的消息机制(可限制消息调用次数)

上代码

/********************************************************
     文件: EasyMsg.cs
     作者: 阿飞
     日期: 2022年02月15日_09:24
     寄语: 虎年 虎虎生威  大吉大利
     功能: 

*********************************************************/


using System;
using System.Collections.Generic;
using UnityEngine;


public enum EasyKeys
{

    None,//默认空事件

    //请自定义事件名称
    测试1,
    测试2,
}
/// <summary>
/// 简易高效枚举消息机制
/// 可以限制消息的调用次数
///同一事件可加入多个方法
/// 
/// 使用简单粗暴 
/// 
/// 要使用请先调用 AddEvent
/// 注销消息调用  RemoveEvent
/// </summary>
public class EasyMsg
{
    static Dictionary<UnityEngine.Object, Dictionary<string, Action<object>>> mRegisteredObjects = new Dictionary<UnityEngine.Object, Dictionary<string, Action<object>>>();

    static Dictionary<string, Action<object>> limitCountEventList = new Dictionary<string, Action<object>> ();
    static Dictionary<string, int> limitCountList = new Dictionary<string, int> ();

    /// <summary>
    /// 注册事件
    /// 一般 awake 中注册
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="eventkey">事件名称 ,提前在 Easykey中 写入枚举</param>
    /// <param name="onMsgReceived"> 使用lambo表达式  (data)=>{function(data);}</param>
    public static void AddEvent(UnityEngine.Object obj, EasyKeys eventkey, Action<object> onMsgReceived,int limitCount=-1)
    {
        string msgName = eventkey.ToString();

        if (!mRegisteredObjects.ContainsKey(obj))
        {
            Dictionary<string, Action<object>> dict = new Dictionary<string, Action<object>>();
            dict.Add(msgName, _ => { });
            dict[msgName] += onMsgReceived;
            mRegisteredObjects.Add(obj, dict);
        }
        else
        {
            if (mRegisteredObjects[obj].ContainsKey(msgName))
            {
                mRegisteredObjects[obj][msgName] += onMsgReceived;
            }
            else
            {
                mRegisteredObjects[obj].Add(msgName, _ => { });
                mRegisteredObjects[obj][msgName] += onMsgReceived;
            }
        }

        //注册限制次数的事件
        if (limitCount !=-1)
        {
            limitCountEventList.Add(msgName, onMsgReceived);
            limitCountList .Add (msgName,limitCount );
        }
    }

   /// <summary>
   /// 移除事件
   /// 销毁物体时必须调用此方法,如果物体上有注册消息的话
   /// </summary>
   /// <param name="obj">在mono中一般用this.gameobject</param>
   /// <param name="eventkey">事件名称</param>
   /// <param name="onMsgReceived">事件中的某个方法</param>
    public static void RemoveEvent(UnityEngine.Object obj, EasyKeys eventkey = EasyKeys.None, Action<object> onMsgReceived = null)
    {
        if (onMsgReceived != null)
        {
            if (mRegisteredObjects.ContainsKey(obj))
            {
                if (mRegisteredObjects[obj].ContainsKey(eventkey.ToString()))
                {                   
                    mRegisteredObjects[obj][eventkey.ToString()] -= onMsgReceived;
                }
                else
                    Debug.Log("移除事件失败,未找到 " + eventkey);
            }
            else
                Debug.Log("移除事件失败,未找到 " + eventkey);

        }
        else if (eventkey != EasyKeys.None)
        {
            if (mRegisteredObjects.ContainsKey(obj))
            {
                if (mRegisteredObjects[obj].ContainsKey(eventkey.ToString()))
                {
                    mRegisteredObjects[obj].Remove (eventkey.ToString());
                }
                else
                    Debug.Log("移除事件失败,未找到 " + eventkey);
            }
            else
                Debug.Log("移除事件失败,未找到 " + eventkey);
        }
        else
        {
            if (mRegisteredObjects.ContainsKey(obj))
            {
                mRegisteredObjects[obj].Remove(eventkey.ToString());
            }
            else
                Debug.Log("移除事件失败,未找到 " + eventkey);
        }
        if (limitCountList .ContainsKey (eventkey.ToString ()))
        {
            limitCountEventList.Remove(eventkey .ToString());
            limitCountList.Remove(eventkey.ToString());
        }
    }
 
   
    /// <summary>
    /// 执行事件
    /// </summary>
    /// <param name="eventkey"></param>
    /// <param name="data"></param>
    public static void Execute(EasyKeys eventkey, object data=null )
    {        
        string msgName = eventkey.ToString();

        foreach (var item in mRegisteredObjects)
        {
            foreach(var obj in item.Value)
            {               
                if (obj.Key == msgName)
                {
                    if (obj.Value !=null )
                    {
                        obj.Value(data);
                    }                                    
                }               
            }               
        }

        //检测事件是否限制次数
        if (limitCountList.ContainsKey(msgName))
        {
            limitCountList[msgName]--;

            if (limitCountList[msgName] <= 0)
            {
                //注销事件                          
                Action<object> cb = limitCountEventList[msgName];
                UnityEngine.Object obj=null;
                foreach (var msg in mRegisteredObjects)
                {
                    foreach (var dic in msg.Value)
                    {
                        if (dic.Key == msgName)
                        {
                            obj = msg.Key;                           
                        }
                    }
                }
                if (obj !=null )
                {
                    RemoveEvent(obj, eventkey, cb);
                    limitCountEventList.Remove(msgName);
                    limitCountList.Remove(msgName);

                    if (mRegisteredObjects[obj][msgName] ==null )
                    {
                        RemoveEvent(obj, eventkey);
                    }
                    
                }
                else
                {
                    Debug.LogError("注销事件失败");
                }
               
              
            }
        }
    }



}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值