Search Unity

Resolved Working with EntityCommandBufferSystems inside ISystem

Discussion in 'DOTS Dev Blitz Day 2022 - Q&A' started by Jonas_DM_, Dec 8, 2022.

  1. Jonas_DM_

    Jonas_DM_

    Joined:
    Feb 28, 2019
    Posts:
    22
    This seems like a common thing to do, but I could not find any documentation on this.

    My question is: What is the current idiomatic way of working with EntityCommandBuffers inside of an ISystem?

    Here's my current understanding:
    I understand that there's a Singleton that is accessible that can create commandbuffers for ECBSystems in Burst code. (IECBSingleton) But these Commandbuffers can't be used in jobs since there's no AddJobHandleForProducer equivalent on the Singleton. It also doesn't seem supported to grab the Singleton in the OnCreate of the ISystem. The Singleton doesn't exist even when calling "state.World.GetOrCreateSystemManaged" on the ECBSystem. Grabbing the Singleton each frame inside the Update does work.
     
  2. Brian_Will

    Brian_Will

    Unity Technologies

    Joined:
    Apr 4, 2020
    Posts:
    13
    It's actually fine that they don't have AddJobHandleForProducer: because your system and the ECBSystem both access the same singleton component type, their state.Dependency handles will be passed to each other (as is the case any time two systems access any of the same component types), and ECB Systems complete their state.Dependency before playing back the ECB's. So your ECB-using jobs will be completed in time, same as with AddJobHandleForProducer.

    The gotcha is that GetSingleton<Foo> will not complete any scheduled jobs that use Foo, so you may need to complete state.Dependency before calling GetSingleton. Usually it's not a concern, though, because singletons are usually passed by value to jobs instead of accessed by jobs directly.
     
  3. Jonas_DM_

    Jonas_DM_

    Joined:
    Feb 28, 2019
    Posts:
    22
    Ah that's quite clever! I didn't consider that.

    The gotcha you mentioned does seem counterintuitive indeed.
    I thought every EntityQuery method to grab data (at least the non-async ones) completed any write dependencies.
    Is GetSingleton the only exception or are there other methods that do this?
    GetSingletonBuffer for example seems to complete its read/write dependencies.

    What is the reasoning behind this exception?
    I get that it returns a read-only copy, but as a user I'd expect it to complete all write jobs (like GetSingletonBuffer(readonly:true) does).

    Thanks @Brian_Will