Support of SystemHandle in EntityCommandBuffer?

I preface this by saying i’m coming back to Unity and now learning ECS.

I decided to create a System from SystemBase (since i do have Managed data in it) and set various ComponentData on it to expose data to other systems or GO (OnGUI stuff). I was debating between adding that data to a singleton entity or directly using the System’s “entity” via SystemHandle.

public partial class MySystem : SystemBase {
  protected override void OnCreate() {
    // ...
    EntityManager.AddComponentData(SystemHandle, new CompA() {});
    EntityManager.AddComponentData(SystemHandle, new CompB() {});
    EntityManager.AddComponentData(SystemHandle, new CompC() {});
    // ...
  }
  protected override void OnUpdate() {
    // ...
    EntityManager.SetComponentData(SystemHandle, new CompA() {});
    EntityManager.SetComponentData(SystemHandle, new CompB() {});
    EntityManager.SetComponentData(SystemHandle, new CompC() {});
    // ...
  }
}

From my understanding, using EntityManager.SetComponentData like this is not great because it creates sync points and we should use EntityCommandBuffer where possible. Am I overthinking this ? Anyways, in my case i could use one of the already available EntityCommandBufferSystem to create an ecb and schedule those changes later and remove the structural changes created by EntityManager.SetComponentData.

I might be wrong but there is no support for SystemHandle in EntityCommandBuffer which is confusing me a little. Is it just not yet supported or maybe an oversight ? Is there a way to get an entity out of a SystemHandle ? I guess i could reference a normal singleton entity instead of using the system as an entity, but it kind of defeat the purpose of SystemHandle doesn’t it ?

SetComponentData doesn’t create any sync point. It’s just like assigning a value to an already existing array element. You don’t allocate new element with this operation.

On EntityCommandBuffer, you should only use it when you want to defer entity creation, deletion, or archetype change operations to some common sync points. Because these operations require structural changes.

EntityCommandBuffer should not be used to set component data. You should just use EntityManager or IJobEntity for this operation.

https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/components-read-and-write.html

In my case it’s probably good enough to use the EntityManager since i’m r/w a handful of components. I’m assuming SetComponentEnabled is also okay since it doesn’t do structural change ?.

-------

On EntityCommandBuffer, you should only use it when you want to defer entity creation, deletion, or archetype change operations to some common sync points. Because these operations require structural changes.

EntityCommandBuffer should not be used to set component data. You should just use EntityManager or IJobEntity for this operation.

The documentation doesn’t explicitly say to not do it, it even says you can:

Deferring component value changes

To defer component value changes for later, use an EntityCommandBuffer which records your intention to write (but not read) component values. These changes only happen when you later play back the EntityCommandBuffer on the main thread.

In my use case, i don’t think it really matters but EntityCommandBuffer, and SystemAPI, should still support SystemHandle, especially if you do structural changes but also to be consistent.

You can doesn’t mean you should. The APIs are there just for really special cases. But yours should just be done with the EntityManager.

About SystemHandle, I never use them and I don’t know them well so I really have nothing to tell you. If I need any singleton component, I’ll just create one with EM.CreateSingleton.