EntityCommandBuffer with Barrier after porting to 2019.x

I am currently porting my project from 2018.3, to 2019.2

Basically I want to know, what is correct approach in 2019.x to barrier, as per 2018.x

[Inject] private BarrierSystem barrier ;

More wordy description of the problem

I managed eliminate all errors at compilation time.

However at runtime I got bunch of bugs now. Mainly related to barrier null reference.
In 2018.x I was using across multiple systems

[Inject] private GenericsBarrier barrier ;

where GenericsBarrier

public class GenericsBarrier : BarrierSystem {}

According to
EntityComponentSystemSamples/ReleaseNotes.md
0.0.23 Upgrade guide

  • BarrierSystem renamed to EntityCommandBufferSystem

Which seams fine.
Then in systems, I could have had

EntityCommandBuffer ecb = barrier.CreateCommandBuffer () ;

Then do whatever with ecb.

That obviously don’t work anymore. No injection.
So what is current correct alternative?

In HeloCube 6 for example
EntityComponentSystemSamples/Samples/Assets/HelloCube/6. SpawnFromEntity/
https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/4e5f45339d81699464ff2d6fbd195ae184d45a7c/Samples/Assets/HelloCube/6. SpawnFromEntity/SpawnerSystem_FromEntity.cs

There is

BeginInitializationEntityCommandBufferSystem m_EntityCommandBufferSystem;

Then in OnCreate () is

// BeginInitializationEntityCommandBufferSystem is used to create a command buffer which will then be played back
// when that barrier system executes.
// Though the instantiation command is recorded in the SpawnJob, it’s not actually processed (or “played back”)
// until the corresponding EntityCommandBufferSystem is updated. To ensure that the transform system has a chance
// to run on the newly-spawned entities before they’re rendered for the first time, the SpawnerSystem_FromEntity
// will use the BeginSimulationEntityCommandBufferSystem to play back its commands. This introduces a one-frame lag
// between recording the commands and instantiating the entities, but in practice this is usually not noticeable.

m_EntityCommandBufferSystem = World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();

m_EntityCommandBufferSystem which is then public EntityCommandBuffer.Concurrent CommandBuffer; in a job can do whatever it needs to do.

And at the bottom of OnUpdate is

// SpawnJob runs in parallel with no sync point until the barrier system executes.
// When the barrier system executes we want to complete the SpawnJob and then play back the commands (Creating the entities and placing them).
// We need to tell the barrier system which job it needs to complete before it can play back the commands.

m_EntityCommandBufferSystem.AddJobHandleForProducer(job);

In 2018.x I had in one system

commandBufferJob.Complete () ;    
barrier.Update ( ) ;

If I am aware, I can achieve same results in 2019.x, with ?

m_EntityCommandBufferSystem.AddJobHandleForProducer(job);

But I don’t want to call this method in every system of course, to not stall main thread.

My confusion, with question

Not sure if I understand this correctly.
But this is not the same as barrier?
How do I now make sure, that two or more system combine command buffers together, before execute at end barrier system? In other words, how I create same behavior of barrier in 2019.x as it was in 2018.x?

I assume something to do with group according to ReleaseNotes.md

But not I don’t follow it yet.

Can somebody kindly enlighten me please, if any of that makes sense? :slight_smile:

I’m not clearly understand your question.
But workflow for barriers is:
In OnCreate you getting barrier from world, in OnUpdate you creating buffer for jobs, and after jobs you register their JH for producer, that’s all. Buffers playback at their order after registered jobs.

1 Like

It not stall main thread, it registers jobs as dependency for buffer for playback later in correct place.

Thx for replay @eizenhorn

My apology for being unclear.
My point was, in 2018.x I could have multiple independent barriers. Like

public class BarrierA: BarrierSystem {}
public class BarrierB : BarrierSystem {}

etc

That of course created separate overhead per each running barrier. Hence keeping lower number of barriers were recommended. But that besides the topic point.

So:

can I have different barriers in same world? Like BarrierA and BarrierB.

I failed initially create them. But I will try again later today.

So if I understand correctly, this works better in comparison to 2018.x?

If I will fail porting at one go, I will take few steps back and start from simple case, with 2-3 systems to test.

You can have as many barriers as you want, they work little bit better than before, for you only changed declaration and some usage things (like manual registering for producer)

1 Like

Have a look at DefaultWorld.cs to see how Unity adds them to the game loop.

1 Like

Thx guys, I will investigate on the matter.