Accessing entities in jobs
C# Job System 可以在worker thread 里面访问entity,在普通的system里面是在main thread里面访问,有两个方法:
- IJobChunk, whose
Execute()
method is called once for each individual chunk matching the query. - IJobEntity, whose
Execute()
method is called once for each entity entity matching the query..
📝 NOTE |
---|
IJobEntity 不是真正意义上的job,因为它继承与IJobChunk .所以 IJobEntity 最终是以 IJobChunk调度的 . |
在job中不能有 structural changes. 只能在main thread 里面才能有 structural changes,但是可以通过把structural change 的命令记录在 EntityCommandBuffer里面,然后再main thread 里面调用
要将IJobChunk或IJobEntity的工作拆分到多个线程中,调用ScheduleParallel()
, chunk 会拆分成多个独立的 batches。
Sync points
'synchronization point' 的操作,是在所有job complete之后,才执行的,比如 EntityManager.CreateEntity()
会首先完成访问组件和实体的jobs. 同样的, the EntityQuery
方法 ToComponentDataArray<T>()
, ToEntityArray()
, and ToArchetypeChunkArray()
会首先完成访问该query的jobs
同样,同步点也会使 DynamicBuffer and ComponentLookup<T>.的实例失效,因为内容变了,需要重新生成实例。
Component safety handles
每一个组件都在其对应的world,有一个safety handle,同一个组件不能同时被两个job 访问,如果访问了 safety handle会报错,只能一个job结束后,再开启另一个job。但是如果该组件是 read-only 则是安全的。
SystemState.Dependency
当在system中调度 job 时,如果需要依赖其它system 中的job ,可以通过 Dependency属性
of SystemState.
在system update 之前:
- system's
Dependency
会complete- 该system的dependency 包括 访问和该system相同组件的system(自动完成)
You're then expected to do two things in every system:
- system update中调度的所有job都应该(直接或间接)依赖于在dependency属性
- 在update的结尾,把该合并的job的handle,赋值给dependency
⚠ IMPORTANT |
---|
Systems 没有跟踪job中使用的native collections,只跟踪 component types,如果两个system都访问同一个native collection,最好是在其中一个system声明,再另一个system 中依赖它 |
ComponentLookup<T>
我们可以通过EntityManager随机访问各个实体的组件,但我们通常不应该在作业中使用EntityManager。应该使用ComponentLookup<T>的类型,它可以通过entity ID Get and Set component value,也可以通过 BufferLookup<T> 来根据 entity ID获取dynamic buffers
⚠ IMPORTANT |
---|
Keep in mind that looking up an entity by ID tends to incur the performance cost of cache misses, so it's generally a good idea to avoid lookups when you can. There are though, of course, many problems which require random lookups to solve, so by no means can random lookups be avoided entirely. Just avoid using them carelessly! |
ComponentLookup<T>、
BufferLookup<T>:
HasComponent()、TryGetComponent<T>() 、 TryGetBuffer<T>()
EntityStorageInfoLookup.:检测是否存在该实体. 返回 EntityStorageInfo struct, which includes a reference to the entity's chunk and its index within the chunk.
ComponentLookup<T>
、 BufferLookup<T> 如果只访问,设置成readonly
ComponentLookup<T>、BufferLookup<T>可以通过
NativeDisableParallelForRestriction 属性,关闭安全性检查,因为parallel job不允许访问不是read-only