ECS 简略版说明二:在job中访问entities

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 之前:

  1.  system's Dependency 会complete
  2. 该system的dependency 包括 访问和该system相同组件的system(自动完成)

You're then expected to do two things in every system:

  1. system update中调度的所有job都应该(直接或间接)依赖于在dependency属性
  2. 在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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TO_ZRG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值