First of all, I’m loving the new features for 0.2.0! Especially the new lamba job scheduling API and burst support for EntityCommandBuffers (both queueing commands AND playback). Although for the latter, when I forget to call EntityCommanBufferSystem.AddJobHandleForProducer after writing to an EntityCommandBuffer.Concurrent supplied by the system, I just get a very unhelpful, run-of-the-mill dependency exception:
The previously scheduled job [JobName] writes to the NativeArray [JobName].Data.Commands. You must call JobHandle.Complete() on the job [JobName], before you can write to the NativeArray safely.
I believe that a better message should include something along the lines of “Did you forget to call EntityCommanBufferSystem.AddJobHandleForProducer”.
ECB Playback() not bursted yet. In this release Unity only added ECB Playback() inside job by ExclusiveEntityTransaction.
Here is how it works from tests.
struct EntityCommandBufferPlaybackJob : IJob
{
public EntityCommandBuffer Buffer;
public ExclusiveEntityTransaction Manager;
public void Execute()
{
Buffer.Playback(Manager);
}
}
[Test]
public void PlaybackWithExclusiveEntityTransactionInJob()
{
var cmds = new EntityCommandBuffer(Allocator.TempJob);
var job = new TestJob {Buffer = cmds};
var e = cmds.CreateEntity();
cmds.AddComponent(e, new EcsTestData { value = 42 });
e = cmds.CreateEntity();
cmds.AddSharedComponent(e, new EcsTestSharedComp(19));
var jobHandle = job.Schedule();
var manager = m_Manager.BeginExclusiveEntityTransaction();
var playbackJob = new EntityCommandBufferPlaybackJob()
{
Buffer = cmds,
Manager = manager
};
m_Manager.ExclusiveEntityTransactionDependency = playbackJob.Schedule(jobHandle);
m_Manager.EndExclusiveEntityTransaction();
cmds.Dispose();
var group = m_Manager.CreateEntityQuery(typeof(EcsTestData));
var arr = group.ToComponentDataArray<EcsTestData>(Allocator.TempJob);
Assert.AreEqual(2, arr.Length);
Assert.AreEqual(42, arr[0].value);
Assert.AreEqual(1, arr[1].value);
arr.Dispose();
group.Dispose();
var sharedGroup = m_Manager.CreateEntityQuery(typeof(EcsTestSharedComp));
var entities = sharedGroup.ToEntityArray(Allocator.TempJob);
Assert.AreEqual(1, entities.Length);
Assert.AreEqual(19, m_Manager.GetSharedComponentData<EcsTestSharedComp>(entities[0]).value);
entities.Dispose();
sharedGroup.Dispose();
}