Unity基础小框架(三):解决事件中心里的装箱拆箱问题

首先写一个最基本的事件中心模块,可以接受参数

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



public class EventCenter : BaseManager<EventCenter>
{
    private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();

    public void EventTrigger(string name, object message)
    {
        if (eventDic.ContainsKey(name))
        {
            eventDic[name]?.Invoke(message);
        }
    }

    public void AddEventListener(string name, UnityAction<object> act)
    {
        if (eventDic.ContainsKey(name))
        {
            eventDic[name] += act;
        }
        else
        {
            eventDic.Add(name, act);
        }
    }

    public void RemoveEventListener(string name, UnityAction<object> act)
    {
        if (eventDic.ContainsKey(name))
        {
            eventDic[name] -= act;
        }
    }
}

虽然此模块已经可以实现基本的功能,但是由于参数类型为object类型,在使用过程中还是会进行装箱拆箱相关的转换,还会耗费一定的性能。所以考虑使用泛型来代替使用obejct做参数传递

using System.Collections;
using System.Collections.Generic;
using UnityEditor.VersionControl;
using UnityEngine;
using UnityEngine.Events;


public interface IEventType { }

public class EventType<T> : IEventType
{
    public UnityAction<T> actions;

    public EventType(UnityAction<T> act)
    {
        actions += act;
    }

}

public class EventType : IEventType 
{
    public UnityAction actions;
    public EventType(UnityAction act)
    {
        actions += act;
    }
}

public class EventCenter : BaseManger<EventCenter>
{
    private Dictionary<string, IEventType> eventDic = new Dictionary<string, IEventType>();

    public void EventTrigger<T>(string name, T message)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType<T>).actions?.Invoke(message);
        }
    }

    public void EventTrigger(string name)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType).actions?.Invoke();
        }
    }

    public void AddEventListener<T>(string name, UnityAction<T> act)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType<T>).actions += act;
        }
        else
        {
            eventDic.Add(name, new EventType<T>(act));
        }
    }

    public void AddEventListener(string name, UnityAction act)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType).actions += act;
        }
        else
        {
            eventDic.Add(name, new EventType(act));
        }
    }

    public void RemoveEventListener<T>(string name, UnityAction<T> act)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType<T>).actions -= act;
        }
    }

    public void RemoveEventListener(string name, UnityAction act)
    {
        if (eventDic.ContainsKey(name))
        {
            (eventDic[name] as EventType).actions -= act;
        }
    }
}

因为希望该模块不用挂载到实际物体身上就能使用,所以让EventType<T> 继承 IEventType接口。利用里氏转换原则,即可正常向字典里添加泛型版本的类对象

使用例:

public class A 
{
    public string name;
}

...

EventCenter.GetInstance().AddEventListener<A>("A类监听", (arg) => 
{
    //具体逻辑
    print(arg.name);
});

...

A a = new a();
a.name = "啦啦啦";

EventCenter.GetInstance().EventTrigger<A>("A类监听", a);

猜你喜欢

转载自blog.csdn.net/XueZhiXia_/article/details/137051499