zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Springboot+shiro配置笔记+错误小结(转)
    Shiro的Filter机制详解---源码分析(转)
    最快最简单的部署本地Apache+PHP+MySQL神器USBWebserver(转)
    shiro简单配置(转)
    重写ajax方法实现异步请求session过期时跳转登录页面(转)
    jquery实现ajax提交form表单的方法总结(转)
    使用ajax提交form表单,包括ajax文件上传
    Spring Boot Freemarker特别篇之contextPath【从零开始学Spring Boot】(转)
    Uncaught SyntaxError: Unexpected token <
    Qt5.5.0在Windows下静态编译(VS2013修改参数以后才能支持XP)good
  • 原文地址:https://www.cnblogs.com/xtxtx/p/11181745.html
Copyright © 2011-2022 走看看