解析ET6的事件的使用

1.事件原理

1.Entry.cs

将所有反射类型添加到EventSystem中

//将dll中的反射类型添加到EventSystem中
Game.EventSystem.Add(CodeLoader.Instance.GetTypes());

2.EventSystem.cs

解析并处理所有EventAttribute标签的类存入allEvents字典,并使用publish分发事件

public void Add(Type[] addTypes)
        {
            this.allTypes.Clear();
            foreach (Type addType in addTypes)
            {
                this.allTypes[addType.FullName] = addType;
            }

            this.types.Clear();
            //获取所有继承BaseAttribute的类型
            List<Type> baseAttributeTypes = GetBaseAttributes(addTypes);
            foreach (Type baseAttributeType in baseAttributeTypes)
            {
                foreach (Type type in addTypes)
                {
                    if (type.IsAbstract)
                    {
                        continue;
                    }

                    object[] objects = type.GetCustomAttributes(baseAttributeType, true);
                    if (objects.Length == 0)
                    {
                        continue;
                    }
                    //将同类型的特性存在一个字典
                    this.types.Add(baseAttributeType, type);
                }
            }

            this.typeSystems = new TypeSystems();
            //遍历所有ObjectSystemAttribute
            foreach (Type type in this.GetTypes(typeof (ObjectSystemAttribute)))
            {
                object obj = Activator.CreateInstance(type);

                if (obj is ISystemType iSystemType)
                {
                    //将每个类打上ObjectSystem标签的类存字典
                    OneTypeSystems oneTypeSystems = this.typeSystems.GetOrCreateOneTypeSystems(iSystemType.Type());
                    oneTypeSystems.Add(iSystemType.SystemType(), obj);
                }
            }

            this.allEvents.Clear();
            //遍历所有EventAttribute
            foreach (Type type in types[typeof (EventAttribute)])
            {
                IEvent obj = Activator.CreateInstance(type) as IEvent;
                if (obj == null)
                {
                    throw new Exception($"type not is AEvent: {obj.GetType().Name}");
                }

                Type eventType = obj.GetEventType();
                if (!this.allEvents.ContainsKey(eventType))
                {
                    this.allEvents.Add(eventType, new List<object>());
                }
                //将同一个eventType的类存入allEvents字典
                this.allEvents[eventType].Add(obj);
            }
        }

 

public async ETTask Publish<T>(T a) where T : struct
        {
            List<object> iEvents;
            //从字典中取出所有eventType的事件类
            if (!this.allEvents.TryGetValue(typeof (T), out iEvents))
            {
                return;
            }

            using (ListComponent<ETTask> list = ListComponent<ETTask>.Create())
            {
                foreach (object obj in iEvents)
                {
                    if (!(obj is AEvent<T> aEvent))
                    {
                        Log.Error($"event error: {obj.GetType().Name}");
                        continue;
                    }
                    //将事件类的run方法存入list
                    list.Add(aEvent.Handle(a));
                }

                try
                {
                    //等待执行所有的run方法
                    await ETTaskHelper.WaitAll(list);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                }
            }
        }

2.事件使用

1.EventType.cs

注册事件结构体

    namespace EventType
    {
        //注册结构体
        public struct ChangePosition
        {
            public Unit Unit;
        }
    }

2.自定义脚本(例子ChangePosition_SyncGameObjectPos.cs)

编写事件触发方法

/继承AEvent<struct>
    public class ChangePosition_SyncGameObjectPos: AEvent<EventType.ChangePosition>
    {
        //重写Run方法
        protected override async ETTask Run(EventType.ChangePosition args)
        {
            //args使用结构体内容
            GameObjectComponent gameObjectComponent = args.Unit.GetComponent<GameObjectComponent>();
            if (gameObjectComponent == null)
            {
                return;
            }
            Transform transform = gameObjectComponent.GameObject.transform;
            transform.position = args.Unit.Position;
            await ETTask.CompletedTask;
        }
    }

3.触发点(事件触发的地方)

//publish传入结构体并初始化参数
Game.EventSystem.Publish(new EventType.ChangePosition() { Unit = this }).Coroutine();

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>