1 min read
30 Jan
30Jan

В 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());
        }
    }
  } 

Ну собственно и все :)

Теперь это работает многопоточно, под берстом и может быть использовано в общем графе систем.

Comments
* The email will not be published on the website.