Are jobs that perform a structural change by default run at the end of the frame?
in other words, is there any point of using an entity command buffer for a system whose sole purpose is to spawn / destroy entities?
this happens often when i need to send / receive rpcs
my thinking is, if it optimised, it should just run at the end of the frame just as the commandbuffersystem is about to update and so it would make no difference if you use .WithStructuralChanges() vs using a CommandBuffer to queue up commands for the EndSimulationEntityCommandBufferSystem because either way those two systems should update at the same time
WIth one note - SetComponentData does not cause synch point (SetSharedComponentData of course does) which completes all jobs in app but only completes the current type dependency chain.
Yes.
When you SetComponentData it only gets dependencies by type index and completes them (and this is expected for me as it’s not structural change and not rearrange chunks, thus other irrelevant types wouldn’t be affected and their dependencies shouldn’t be completed but only current type dependency chain (which of course can contain other types if you share\combine handles but it’s another story) ):
void CompleteReadAndWriteDependencyNoChecks(int type)
{
var withoutFlags = type & TypeManager.ClearFlagsMask;
var arrayIndex = m_TypeArrayIndices[withoutFlags];
if (arrayIndex != NullTypeIndex)
{
for (var i = 0; i < m_DependencyHandles[arrayIndex].NumReadFences; ++i)
m_ReadJobFences[arrayIndex * kMaxReadJobHandles + i].Complete();
m_DependencyHandles[arrayIndex].NumReadFences = 0;
m_DependencyHandles[arrayIndex].WriteFence.Complete();
}
}
As you can see it only complete WriteFence and m_ReadJobFences for specific arrayIndex (type index from m_TypeArrayIndices)
Synch Point trigger call similar code, but instead of using a specific index from m_DependencyHandles it iterate through whole m_DependencyHandles
Which starts from BeforeStructuralChange (as they always trigger synch point) which in turn call DependencyManager->CompleteAllJobsAndInvalidateArrays();, which in the end completes all dependency chains:
for (int t = 0; t < m_DependencyHandlesCount; ++t)
{
m_DependencyHandles[t].WriteFence.Complete();
var readFencesCount = m_DependencyHandles[t].NumReadFences;
var readFences = m_ReadJobFences + t * kMaxReadJobHandles;
for (var r = 0; r != readFencesCount; r++)
readFences[r].Complete();
m_DependencyHandles[t].NumReadFences = 0;
}
ClearDependencies();