ECS:Overview

ECS概念

核心思想:Data-Oriented Tech Stack,不同于传统的Object-Oriented方式。
E:entities
C:components——data
S:systems——behaviour
上图中System读取Translation和Roation,让后将运算结果更新到LocalToWorld component。所以一个System是和一组Componets绑定的,只要拥有这个组合的Entity,这个System都会更新其数据(component)。
 
Archetypes:原型,表示一个唯一的components的组合叫做一个原型。
上图中EntityA和EntityB属于一个原型,EntityC属于另一个原型。
 
内存结构:ECS以chunks为单位分配内存,每个对应一个ArchetypeChunk。
ArchetypeChunk:原型块
    拥有相同Archetype的Entities的所有Components存放在同一块unmanaged memory里,这个非托管的内存块就叫ArchtypeChunk。
    如果enitty的archetype变化了(增删components),它的components的存储chunk也会变化。
    archetye和chunk的关系:一对多。
    可以根据archetype就能找到所有有用这个components组合的entities,效率高,因为archetypes的数量有限。如果直接遍历所有entities则数据量就非常大了。
    chunk位置更新算法:
    (1)chunk始终保持紧密排列,无序
    (2)entity创建或增删components时,它会被放置在其archetype对应的第一个有空位的的chunk里面
    (3)当一个entity从archetype中移除时,首先会在chunk中移除该enity对应的components,然后将chunk中最后一个entity移到这个空位填充,保持紧密排列
    shared components共享组件规则:
    (1)共享组件的值会影响entities存储的chunk
    (2)同一个chunk中的shared components的values一定一样
    (3)如果修改一个entity的shared component的value,会导致这个entity移动到别的chunk
    (4)移动的时候,有可能需要创建新的chunk
    (5)尽量使用shared components,因为它的性能更高,eg:RenderMesh component
 
Entity查询:EntityQuery
    根据components需求获取所有满足该需求的entities列表。
    一次query会返回一个满足需求的chunks列表。然后可以使用IJobChunk来访问这些components数据,或者使用IJobForEach或 non-Job for-each loop。
    注意:IJobForEach隐式创建一个entity query。
 
Jobs:JobComponentSystem
    为了充分利用Job System,ECS提供了JobComponentSystem,以及Job类型IJobForEACH和IJobChunk,用来在main thread外处理数据。
    IJobForEach/IJobForEachwithEntity通常是用起来最简单的。
    IJobChunk可以用来处理IJobForEach处理不了的复杂情况。
    这些ECS Jobs使用一了个EntityQuery对象,不只是用来标记需要的components组合,而且可以指定需要的component的read-only或read-write状态。这个访问标记决定了Job scheduler在以什么方式来调度job:
    (1)read-only的job可以run in parallel;
    (2)write的job当有其他job在访问同样的数据时则是run in sequence。
 
System组织形式:World和group
    ECS提供World和group来组织systems。
    默认情况下,ECS会创建一个default World和一组预定义的groups,然后它会找到所有的systems,实例化以后添加到预定义的simulation group里。
    你可以指定一个group内部不同systems update的时序。
    group本身也是一个system,所以可以将一个group添加到另一个group,并指定其update顺序。
    一个group里面的所有systems会在下一个system或group之前update。
    如果不指定update order,一组systems始终会以不依赖于创建时序的某种特定顺序执行。也就是说同样一组systems,它的执行顺序一定是确定的,不存在随机性。
    System的update在main thread执行。但system可以使用job让任务运行在worker thread。
 
 
 
posted @ 2020-02-09 13:09  斯芬克斯  阅读(591)  评论(0编辑  收藏  举报