本文最后更新于6 天前,其中的信息可能已经过时,如有错误请发送邮件到nanshaws360@gmail.com
在Artemis ECS(Entity Component System)框架中,World 类是核心管理类,负责管理实体(Entity)、组件(Component)和系统(System)。World 类的初始化流程主要由其构造方法和相关配置(如WorldConfiguration)驱动。以下是World类初始化流程的详细介绍:
1. 构造方法 World(WorldConfiguration configuration):
World的构造方法接收一个WorldConfiguration对象,用于配置World的初始化。这个构造方法主要完成以下步骤:
partition和systemsBag初始化:partition是WorldSegment的一个实例,持有injector和systems(系统的class->系统实例映射)。systemsBag是WorldConfiguration中系统的集合。
ComponentManager、EntityManager、AspectSubscriptionManager初始化:ComponentManager(cm)、EntityManager(em) 和AspectSubscriptionManager(asm) 是World的核心管理器,用于管理组件、实体和系统之间的关系。如果这些管理器在配置中已经被初始化(默认被null占据位置,未提供修改方法),则直接使用;否则创建新的实例。
BatchChangeProcessor和alwaysDelayComponentRemoval初始化:batchProcessor是一个批量处理组件变化的工具。alwaysDelayComponentRemoval表示是否总是延迟移除组件,这个配置值来自于WorldConfiguration。
- 调用
WorldConfiguration的initialize方法:- 该方法将
World实例本身传入,完成更复杂的初始化逻辑(核心)。
- 该方法将
2. WorldConfiguration 的初始化 (initialize):
该方法在World的构造方法中被调用,负责初始化World的核心逻辑,主要完成以下工作:
- 设置调用策略 (
InvocationStrategy):- 如果没有定义自定义的调用策略,则创建一个默认的
InvocationStrategy实例,并将其与World绑定。
- 如果没有定义自定义的调用策略,则创建一个默认的
- 核心系统初始化:
- 系统集合中的前三个位置(
systems列表)分别被设置为ComponentManager、EntityManager和AspectSubscriptionManager,这些是Artemis的核心系统,默认情况下不可替换。
- 系统集合中的前三个位置(
- 注册和初始化系统:
- 遍历所有的系统(包括核心系统和用户自定义的系统),将其添加到
World的分区系统集合partition中,并进行如下逻辑:- 设置每个系统的
World实例。 - 如果系统是一个
Manager,调用其registerManager方法进行注册。
- 设置每个系统的
Injector初始化WiredFieldResolver、ArtemisFieldResolver、AspectFieldResolver。WiredFieldResolver:ArtemisFieldResolver: 负责系统的注入。可以注入顶层的抽象类型系统,如B0继承于A,可以在属性声明时用A,如果有多个继承于A,会导致前面被后面的覆盖(注入不准确)AspectFieldResolver:
injector注入配置WorldConfiguration里系统的属性。- 调用
WorldConfiguration里每个系统的initialize方法完成初始化。
- 遍历所有的系统(包括核心系统和用户自定义的系统),将其添加到
AspectSubscriptionManager处理:- 调用
asm.processComponentIdentity(NO_COMPONENTS, new BitVector())方法,用于处理组件的身份验证。
- 调用
- 设置和初始化调用策略:
- 将系统集合设置到调用策略中,并初始化策略,以确保系统按预期顺序被调用。
3. Injector 的初始化 (CachedInjector.initialize):
在WorldConfiguration的initialize方法中,Injector用于处理依赖注入,具体操作包括:
FieldHandler初始化:FieldHandler负责处理字段注入。它通过不同的FieldResolver来解析和注入字段依赖。
- 处理注入依赖:
- 遍历所有的
FieldResolver,将其初始化并与World实例关联。如果用户自定义的依赖无法被解析,抛出InjectionException异常。
- 遍历所有的






