• EventSystem 事件系统


    EventSystem 事件系统

    事件系统在开发中必不可少事件系统使用观察者模式可以极大程度降低程序的耦合,之前的文章也讲过事件系统但是不够高效简洁,如何轻便高效优雅的实现一个事件呢?依然基于之前的AssemblyManager 程序集管理器SingletonSystem 单例管理系统进行开发,主要原理也是根据反射去获取事件的接口使用反射进行实例化处理类,而非人工手动订阅事件。

    1.IEvent

    public interface IEvent
    {
        Type GetEventType();
        void Invoke(object self);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.EventHandler

    public abstract class EventHandler<T> : IEvent where T : struct
    {
        private readonly Type _selfType = typeof(T);
        public Type GetEventType()
        {
            return _selfType;
        }
        public abstract void Handler(T eventStruct);
        public void Invoke(object self)
        {
            try
            {
                Handler((T)self);
            }
            catch (Exception ex)
            {
                Debug.LogError($"{_selfType.Name} Error : {ex.Message}");
                return;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.EventInfo

    public sealed class EventInfo
    {
        public readonly Type Type;
        public readonly IEvent Event;
    
        public EventInfo(Type type, IEvent @event)
        {
            Type = type;
            Event = @event;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.EventSystem

    public class EventSystem : Singleton<EventSystem>
    {
        private readonly OneToManyList<Type, IEvent> _events = new();
        private readonly OneToManyList<int, EventInfo> _assemblyEvents = new();
        protected override void Load(int assemblyName)
        {
            foreach (Type type in AssemblyManager.ForEach(assemblyName, typeof(IEvent)))
            {
                IEvent @event = (IEvent)Activator.CreateInstance(type);
                if (@event != null)
                {
                    Type thisType = @event.GetEventType();
                    _events.Add(thisType, @event);
                    _assemblyEvents.Add(assemblyName, new EventInfo(thisType, @event));
                }
            }
        }
    
        protected override void UnLoad(int assemblyName)
        {
            if(_assemblyEvents.TryGetValue(assemblyName,out List<EventInfo> events))
            {
                foreach (EventInfo info in events)
                {
                    _events.RemoveValue(info.Type, info.Event);
                }
    
                _assemblyEvents.RemoveByKey(assemblyName);
            }
        }
    
        public void Publish<TEventData>(TEventData eventData) where TEventData : struct
        {
            if (!_events.TryGetValue(eventData.GetType(), out List<IEvent> list))
                return;
    
            foreach (IEvent @event in list)
            {
                try
                {
                    @event?.Invoke(eventData);
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex.Message);
                    return;
                }
            }
        }
    
        public override void Dispose()
        {
            _events.Clear();
            _assemblyEvents.Clear();
            base.Dispose();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    这里的每个事件传递的参数可以使用引用池进行管理避免重复创建相同的对象消耗性能。

    5.测试

    public class Test : MonoBehaviour
    {
        void Start()
        {
            SingletonSystem.Initialize();
            AssemblyManager.Initialize();
        }
    
    
        private void Update()
        {
            SingletonSystem.Update();
    
            if (Input.GetKeyDown(KeyCode.P))
            {
                EventSystem.Instance.Publish<AgeEvent>(new AgeEvent() { Age = 18 });
            }
        }
    }
    
    public struct AgeEvent
    {
        public int Age;
    }
    
    public class AgeChangeHandler : EventHandler<AgeEvent>
    {
        public override void Handler(AgeEvent eventStruct)
        {
            Debug.Log(eventStruct.Age);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    vue 笔记03
    基于Docker构建MySQL主从复制数据库
    “CarrotMovement“ app Tech Support(URL)
    Multisim14.0仿真使用汇总
    linux 安装中文字体
    ClickHouse 存算分离改造:小红书自研云原生数据仓库实践
    uni-app本地存储
    【MDPI出版社】物联网通信类SCI&EI,仅2-3个月左右录用
    el-upload添加请求头
    【Numpy-矩阵库~python】
  • 原文地址:https://blog.csdn.net/zzzsss123333/article/details/132634921