• ET游戏框架整理笔记2: 加载组件都干了啥事


    main函数中加载完dll就是 接下来就是挂载组件 那么加载组件都干了什么事呢

    加载组件主要做的事情

    1. 组件工厂创建组件 

    根据frompool参数选择从缓存池取或者反射创建一个组件 创建的组件都有一个instanceid的 属性 组件的唯一表示

         component = (T)Activator.CreateInstance(type);

    2. 添加组件到Game的eventsystem字典中  注意这个是全局的EventSystem

    Game.EventSystem.Add(component);

    public void Add(Component component)
             {
                 this.allComponents.Add(component.InstanceId, component);

                Type type = component.GetType();

                if (this.loadSystems.ContainsKey(type))
                 {
                     this.loaders.Enqueue(component.InstanceId);
                 }

                if (this.updateSystems.ContainsKey(type))
                 {
                     this.updates.Enqueue(component.InstanceId);
                 }

                if (this.startSystems.ContainsKey(type))
                 {
                     this.starts.Enqueue(component.InstanceId);
                 }

                if (this.lateUpdateSystems.ContainsKey(type))
                 {
                     this.lateUpdates.Enqueue(component.InstanceId);
                 }
            }

    可以看到  Game.EventSystem.Add(component); 就干了2件事  

    ①把组件添加到全局字典

    ②根据各类 system字典是否包含组件type 加到个格子事件队列中  

    this.updateSystems等字典中的数据从哪来的  ?

    上一节中有说到加载dll过程中相关代码 

    遍历程序集所有标记有ObjectSystemAttribute标签的类 =>找实现了相应接口 如实现了IUpdateSystem接口 就把该type加到this.updateSystems字典中

    foreach (Type type in types[typeof(ObjectSystemAttribute)])
                 {
                     object[] attrs = type.GetCustomAttributes(typeof(ObjectSystemAttribute), false);

                    if (attrs.Length == 0)
                     {
                         continue;
                     }

                    object obj = Activator.CreateInstance(type);

                    switch (obj)
                     {
                         case IAwakeSystem objectSystem:
                             this.awakeSystems.Add(objectSystem.Type(), objectSystem);
                             break;
                         case IUpdateSystem updateSystem:
                             this.updateSystems.Add(updateSystem.Type(), updateSystem);
                             break;
                         case ILateUpdateSystem lateUpdateSystem:
                             this.lateUpdateSystems.Add(lateUpdateSystem.Type(), lateUpdateSystem);
                             break;
                     }
                 }

    比如下面这个类TimerComponentUpdateSystem              UpdateSystem是实现了IUpdateSystem接口的

    [ObjectSystem]
    public class TimerComponentUpdateSystem : UpdateSystem<TimerComponent>
    {
         public override void Update(TimerComponent self)
         {
             self.Update();
         }
    }

    现在知道了  this.updateSystems等字典中数据是在程序开始加载dll时根据type作为key 实例作为value缓存起来的

    那么  this.updates.Enqueue(component.InstanceId);  又是为了什么呢?  这里还不清楚

     

    3. 调用组件iawake接口

    Game.EventSystem.Awake(component);

    如果组件实现了IAwake接口的话 调用该接口的Run方法 Run方法调用子类实现的Awake方法

    比如上面贴的那个 TimerComponentUpdateSystem类

    4. 创建完组件, 添加到父附件的组件字典中

    this.componentDict.Add(type, component

  • 相关阅读:
    java实现DAG广度优先便利
    java实现图分组
    四。字符串
    二。链表
    一。数组
    TypeScript学习(六)@types包
    TypeScript学习(五)三斜线指令
    TypeScript学习(四)声明文件和declare关键字
    TypeScript学习(三)命名空间和模块
    TypeScript学习(二)函数重载
  • 原文地址:https://www.cnblogs.com/xtxtx/p/11181745.html
Copyright © 2020-2023  润新知