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。