Programming/ECS -1.0
EntityCommandBuffer
Inner-Peace
2023. 1. 5. 14:15
반응형
멀티스레드 환경에서 하나의 데이터에 변경 작업을 하면 경쟁 문제가 발생한다.
그래서 멀티스레드 환경에서 원활하게 변경 작업을 할 수 있도록 만든것.
EntityCommandBuffer는 작업 큐에 저장을 해두고 해당 프레임이 완료되면 큐에 저장된 버퍼들을 처리되도록 함.
단일 스레드에서 사용법
// ... in a system update
// You don't specify a size because the buffer will grow as needed.
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
// The ECB is captured by the ForEach job.
// Until completed, the job owns the ECB's job safety handle.
Entities
.ForEach((Entity e, in FooComp foo) =>
{
if (foo.Value > 0)
{
// Record a command that will later add
// BarComp to the entity.
ecb.AddComponent<BarComp>(e);
}
}).Schedule();
this.Dependency.Complete();
// Now that the job is completed, you can enact the changes.
// Note that Playback can only be called on the main thread.
ecb.Playback(this.EntityManager);
// You are responsible for disposing of any ECB you create.
ecb.Dispose();
동시에 작업하려면
// ... in a system update
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
// We need to write to the ECB concurrently across threads.
EntityCommandBuffer.ParallelWriter ecbParallel = ecb.AsParallelWriter();
// The entityInQueryIndex is unique for each entity and will be
// consistent for each particular entity regardless of scheduling.
Entities
.ForEach((Entity e, int entityInQueryIndex, in FooComp foo) => {
if (foo.Value > 0)
{
// The first arg is the 'sort key' recorded with the command.
ecbParallel.AddComponent<BarComp>(entityInQueryIndex, e);
}
}).Schedule();
// Playback is single-threaded as normal.
this.Dependency.Complete();
// To ensure deterministic playback order,
// the commands are first sorted by their sort keys.
ecb.Playback(this.EntityManager);
ecb.Dispose();
EntityCommandBuffer를 여러번 사용하는 방법
PlaybackPolicy.MultiPlayback 을 붙여줘야 한다 ( 안붙여주면 오류 )
// ... in a system update
EntityCommandBuffer ecb =
new EntityCommandBuffer(Allocator.TempJob, PlaybackPolicy.MultiPlayback);
// ... record commands
ecb.Playback(this.EntityManager);
// Additional playbacks are OK because this ECB is MultiPlayback.
ecb.Playback(this.EntityManager);
ecb.Dispose();
EntityCommandBufferSystem을 사용해서 버퍼를 만들면 실행과 해제를 자동으로 해준다.
public class BufferSystem : EntityCommandBufferSystem
{
}
기본적인 버퍼 시스템
- BeginInitializationEntityCommandBufferSystem
- EndInitializationEntityCommandBufferSystem
- BeginSimulationEntityCommandBufferSystem
- EndSimulationEntityCommandBufferSystem
- BeginPresentationEntityCommandBufferSystem
반응형