В ME.BECS можно очень легко и без гемора работать с данными многопоточно.
Давайте разберем как это выглядит на примере простой системы:
- У нас есть сущности с компонентом:
struct ReloadableComponent { public float reloadTimer; // время текущей перезарядки public float reloadTime; // сколько идет перезарядка }
- Нам нужно выбрать все сущности, на которых нет ReloadedComponent
- Для каждой сущности нужно покрутить таймер перезарядки
- Если перезарядка завершена - добавить компонент ReloadedComponent
Итак, приступим.
Сначала создадим систему:
struct ReloadSystem : IUpdate { public void OnUpdate(ref SystemContext context) { } }
Теперь в метод OnUpdate добавим фильтр по нашему компоненту и каркас для джобы:
struct ReloadSystem : IUpdate { [BurstCompile] public struct Job : IJobParallelForComponents<ReloadableComponent> { public float dt; public void Execute(in Ent ent, ref ReloadedComponent component) { // тут напишем саму джобу } } public void OnUpdate(ref SystemContext context) { var dependsOn = API.Query(in context) .Without<ReloadedComponent>() .With<ReloadableComponent>() .ScheduleParallelFor<Job, ReloadableComponent>(new Job() { dt = context.deltaTime, }); context.SetDependency(dependsOn); } }
А теперь добавим саму логику джобы:
public struct Job : IJobParallelForComponents<ReloadableComponent> { public float dt; public void Execute(in Ent ent, ref ReloadedComponent component) { component.reloadTimer += this.dt; if (component.reloadTimer >= component.reloadTime) { ent.Set(new ReloadedComponent()); } } }
Ну собственно и все :)
Теперь это работает многопоточно, под берстом и может быть использовано в общем графе систем.