Class CommandBuffer<ECS_TYPE>

java.lang.Object
com.hypixel.hytale.component.CommandBuffer<ECS_TYPE>
Type Parameters:
ECS_TYPE -
All Implemented Interfaces:
ComponentAccessor<ECS_TYPE>

public class CommandBuffer<ECS_TYPE> extends Object implements ComponentAccessor<ECS_TYPE>
The CommandBuffer is a critical part of the component system.

Any time you wish to add/remove a component or entity while iterating/ticking the CommandBuffer is required, this is for two reasons.

  1. To prevent modification of ArchetypeChunk's and/or Store's while iterating/ticking.
  2. To improve performance by reducing the scope of memory access for a system while iterating/ticking.

TODO: Reference to tutorial on how to make a component system.

A CommandBuffer is owned and can only be used by a single thread, when operating on a parallel task we fork the CommandBuffer by using fork() and then later join the buffers together with mergeParallel(CommandBuffer). This allows for faster single threaded access while retaining the ability to distribute workloads across multiple threads in parallel.

  • Method Details

    • getStore

      @Nonnull public Store<ECS_TYPE> getStore()
      Returns:
      the Store that this command buffer is associated with
    • run

      public void run(@Nonnull Consumer<Store<ECS_TYPE>> consumer)
      Called to execute logic within the scope of the store affiliated with this command buffer
      Parameters:
      consumer - The functionality that is to be executed
    • getComponent

      public <T extends Component<ECS_TYPE>> T getComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Allows access to components in the store without checking the Store.assertThread().

      This is safe as long as the CommandBuffer's is never stored in a field outside the Store by systems and the component that is fetched is not modified without having thread-safe handling for that components' data.

      See Store.getComponent(Ref, ComponentType) for internal call.

      Specified by:
      getComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The type of the component
      Parameters:
      ref - The entity reference of the entity
      componentType - The components type that we are getting
      Returns:
      the component
    • getArchetype

      @Nonnull public Archetype<ECS_TYPE> getArchetype(@Nonnull Ref<ECS_TYPE> ref)
      Allows access to the archetype associated with the given entity reference.

      See Store.getArchetype(Ref) for internal call.

      Specified by:
      getArchetype in interface ComponentAccessor<ECS_TYPE>
      Parameters:
      ref - The entity reference of the entity that we are fetching the archetype for.
      Returns:
      the Archetype associated with the entity.
    • getResource

      @Nonnull public <T extends Resource<ECS_TYPE>> T getResource(@Nonnull ResourceType<ECS_TYPE,T> resourceType)
      Allows access to resources in the store without checking the Store.assertThread().

      This is safe as long as the CommandBuffer's is never stored in a field outside the Store by systems and the resource that is fetched is not modified without having thread-safe handling for that resource's data.

      See Store.getResource(ResourceType) for internal call.

      Specified by:
      getResource in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - the type of the resource
      Parameters:
      resourceType - the resource's type
      Returns:
      the component
    • getExternalData

      @Nonnull public ECS_TYPE getExternalData()
      Specified by:
      getExternalData in interface ComponentAccessor<ECS_TYPE>
      Returns:
      the external data of the store that is associated with this command buffer.
    • addEntities

      @Nonnull public Ref<ECS_TYPE>[] addEntities(@Nonnull Holder<ECS_TYPE>[] holders, @Nonnull AddReason reason)
      Called to add the given array of entity holders to the store associated with this command buffer.

      See Store.addEntity(Holder, Ref, AddReason) for internal call.

      Specified by:
      addEntities in interface ComponentAccessor<ECS_TYPE>
      Parameters:
      holders - The array of entity holders to be added.
      reason - The provided add reason for why these entities are being added.
      Returns:
      an array of entity references for the holders that have been added.
    • addEntity

      @Nonnull public Ref<ECS_TYPE> addEntity(@Nonnull Holder<ECS_TYPE> holder, @Nonnull AddReason reason)
      Called to add the given entity holder to the store associated with this command buffer.

      See Store.addEntity(Holder, AddReason) for internal call.

      Specified by:
      addEntity in interface ComponentAccessor<ECS_TYPE>
      Parameters:
      holder - The entity holder to be added.
      reason - The provided add reason for why these entities are being added.
      Returns:
      the entity reference of the holder that has been added.
    • addEntity

      @Nonnull public Ref<ECS_TYPE> addEntity(@Nonnull Holder<ECS_TYPE> holder, @Nonnull AddReason reason, @Nullable Ref<ECS_TYPE> parent)
      Called to add the given entity holder to the store, owned by parent.

      The parent is resolved when the queue drains, not now, so queueing the parent's own addEntity first in the same buffer is enough to make it valid in time. If the parent is gone by then, or has become a child itself, the child is not added and its reference stays invalid.

      See Store.addEntity(Holder, Ref, AddReason, Ref) for internal call.

      Parameters:
      holder - The entity holder to be added.
      reason - The provided add reason for why this entity is being added.
      parent - The entity that owns the new entity, or null for the store root.
      Returns:
      the entity reference of the holder that has been added.
    • addEntities

      public void addEntities(@Nonnull Holder<ECS_TYPE>[] holders, int holderStart, @Nonnull Ref<ECS_TYPE>[] refs, int refStart, int length, @Nonnull AddReason reason)
      Adds a subsection of the entities in the holders array to the world, storing the references in the reference array.

      See Store.addEntities(Holder[], int, Ref[], int, int, AddReason) for internal call.

      Parameters:
      holders - The holders containing entities to add to the world.
      holderStart - The offset in the holder array to add from.
      refs - The reference array that will contain the new entity references for the created entities.
      refStart - The offset in the reference array to start writing.
      length - Number entities to spawn.
      reason - The reason the entities are being added.
    • addEntities

      public void addEntities(@Nonnull Holder<ECS_TYPE>[] holders, int holderStart, @Nonnull Ref<ECS_TYPE>[] refs, int refStart, int length, @Nonnull AddReason reason, @Nullable Ref<ECS_TYPE> parent)
      Adds a subsection of the entities in the holders array to the world, all owned by parent.

      See Store.addEntities(Holder[], int, Ref[], int, int, AddReason, Ref) for internal call.

      Parameters:
      holders - The holders containing entities to add to the world.
      holderStart - The offset in the holder array to add from.
      refs - The reference array that will contain the new entity references for the created entities.
      refStart - The offset in the reference array to start writing.
      length - Number entities to spawn.
      reason - The reason the entities are being added.
      parent - The entity that owns every new entity, or null for the store root.
    • addEntity

      @Nonnull public Ref<ECS_TYPE> addEntity(@Nonnull Holder<ECS_TYPE> holder, @Nonnull Ref<ECS_TYPE> ref, @Nonnull AddReason reason)
      Adds an entity and uses the provided entity reference.

      See Store.addEntity(Holder, Ref, AddReason) for internal call.

      Parameters:
      holder - The entity holder to be added.
      ref - The entity reference of the entity to add.
      reason - The provided add reason for why these entities are being added.
      Returns:
      The reference for the added entity which will become valid after this system has finished ticking.
    • addEntity

      @Nonnull public Ref<ECS_TYPE> addEntity(@Nonnull Holder<ECS_TYPE> holder, @Nonnull Ref<ECS_TYPE> ref, @Nonnull AddReason reason, @Nullable Ref<ECS_TYPE> parent)
      Adds an entity owned by parent, using the provided entity reference.

      See Store.addEntity(Holder, Ref, AddReason, Ref) for internal call.

      Parameters:
      holder - The entity holder to be added.
      ref - The entity reference of the entity to add.
      reason - The provided add reason for why this entity is being added.
      parent - The entity that owns the new entity, or null for the store root.
      Returns:
      The reference for the added entity which will become valid after this system has finished ticking.
    • setParent

      public void setParent(@Nonnull Ref<ECS_TYPE> ref, @Nullable Ref<ECS_TYPE> parent)
      Moves an entity to a different owner.

      The move is dropped, not thrown, when the queue drains into a store the move no longer fits: either reference is gone, ref has acquired children, or parent has itself become a child. Another fork can cause any of these, so the caller cannot rule them out.

      See Store.setParent(Ref, Ref) for internal call.

      Parameters:
      ref - The entity reference of the entity to move.
      parent - The new owner, or null to give the entity back to the store root.
    • copyEntity

      @Nonnull public Holder<ECS_TYPE> copyEntity(@Nonnull Ref<ECS_TYPE> ref, @Nonnull Holder<ECS_TYPE> target)
      Copies an entity and adds it to the target holder.

      See Store.copyEntity(Ref, Holder) for internal call.

      Parameters:
      ref - reference to the entity to remove.
      target - the entity holder to put the data.
      Returns:
      An entity holder for the copy of the entity that will be populated after this system has finished ticking.
    • tryRemoveEntity

      public void tryRemoveEntity(@Nonnull Ref<ECS_TYPE> ref, @Nonnull RemoveReason reason)
      Called to try to remove the given entity with the given reason.

      Attempts to remove the entity via the store, first checking whether the entities reference is valid.

      Parameters:
      ref - The entity reference of the entity that we are trying to remove.
      reason - The removal reason for why we are trying to remove this entity.
    • removeEntity

      public void removeEntity(@Nonnull Ref<ECS_TYPE> ref, @Nonnull RemoveReason reason)
      Called to remove the given entity with the given reason.

      A ref that is dead at drain is a caller bug and fails loudly. Use tryRemoveEntity(Ref, RemoveReason) when the entity can be gone by then, e.g. removed as a child of a removed parent.

      See Store.removeEntity(Ref, Holder, RemoveReason, Throwable) for internal call.

      Parameters:
      ref - The entity reference of the entity that we are removing.
      reason - The removal reason for why we are removing this entity.
    • removeEntity

      @Nonnull public Holder<ECS_TYPE> removeEntity(@Nonnull Ref<ECS_TYPE> ref, @Nonnull Holder<ECS_TYPE> target, @Nonnull RemoveReason reason)
      Description copied from interface: ComponentAccessor
      Called to remove the given entity from the store of this component accessor.
      Specified by:
      removeEntity in interface ComponentAccessor<ECS_TYPE>
      Parameters:
      ref - The entity reference of the entity being removed.
      target - The holder of the entity being removed.
      reason - The reason that we are removing this entity.
      Returns:
      the holder of the removed entity.
    • ensureComponent

      public <T extends Component<ECS_TYPE>> void ensureComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Ensures the existence of a component, assigning a fresh instance of the component to the entity should it not already exist

      See Store.ensureComponent(Ref, ComponentType) for internal call.

      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity.
      componentType - The component type of the component to ensure.
    • ensureAndGetComponent

      @Nonnull public <T extends Component<ECS_TYPE>> T ensureAndGetComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Called to both ensure and fetch the component of the given type from the given entity.

      See Store.addComponent(Ref, ComponentType, Component) for internal call.

      Specified by:
      ensureAndGetComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are ensuring and getting the component from.
      componentType - The component type of the component that we are ensuring and getting.
      Returns:
      the component instance of the given component type.
    • addComponent

      @Nonnull public <T extends Component<ECS_TYPE>> T addComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Called to add the given component type to the given entity. This adds a fresh new copy of the component to the entity.

      See Store.addComponent(Ref, ComponentType) for internal call.

      Specified by:
      addComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are adding a component to.
      componentType - The component type of the component that we are adding.
      Returns:
      the component instance of the component that we have added.
    • addComponent

      public <T extends Component<ECS_TYPE>> void addComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType, @Nonnull T component)
      Called to add the given component type to the given entity. This adds a fresh new copy of the component to the entity.

      See Store.addComponent(Ref, ComponentType, Component) for internal call.

      Specified by:
      addComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are adding a component to.
      componentType - The component type of the component that we are adding.
      component - The component instance that we are adding to the entity.
    • replaceComponent

      public <T extends Component<ECS_TYPE>> void replaceComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType, @Nonnull T component)
      Called to replace the component instance of an entity with another component instance based on the given component type.

      See Store.replaceComponent(Ref, ComponentType, Component) for internal call.

      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are replacing a component for.
      componentType - The component type of the component that we are replacing.
      component - The component instance that we are replacing the existing component instance with.
    • removeComponent

      public <T extends Component<ECS_TYPE>> void removeComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Called to remove the component of the given type from the given entity.
      Specified by:
      removeComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are removing the component from.
      componentType - The component type of the component that we are removing.
    • tryRemoveComponent

      public <T extends Component<ECS_TYPE>> void tryRemoveComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType)
      Description copied from interface: ComponentAccessor
      Called to try to remove the component og the given type from the given entity.
      Specified by:
      tryRemoveComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component type based on the store type.
      Parameters:
      ref - The entity reference of the entity that we are removing the component from.
      componentType - The component type of the component that we are removing.
    • putComponent

      public <T extends Component<ECS_TYPE>> void putComponent(@Nonnull Ref<ECS_TYPE> ref, @Nonnull ComponentType<ECS_TYPE,T> componentType, @Nonnull T component)
      Description copied from interface: ComponentAccessor
      Called to put the given component onto the given entity.
      Specified by:
      putComponent in interface ComponentAccessor<ECS_TYPE>
      Type Parameters:
      T - The component class type.
      Parameters:
      ref - The entity reference of the entity.
      componentType - The component type of the component being put.
      component - The component instance that is being put.
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull Ref<ECS_TYPE> ref, @Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull EntityEventType<ECS_TYPE,Event> systemType, @Nonnull Ref<ECS_TYPE> ref, @Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull Holder<ECS_TYPE> holder, @Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull EntityHolderEventType<ECS_TYPE,Event> systemType, @Nonnull Holder<ECS_TYPE> holder, @Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • invoke

      public <Event extends EcsEvent> void invoke(@Nonnull WorldEventType<ECS_TYPE,Event> systemType, @Nonnull Event param)
      Specified by:
      invoke in interface ComponentAccessor<ECS_TYPE>
    • fork

      @Nonnull public CommandBuffer<ECS_TYPE> fork()
      Attempts to fork a command buffer instance from the store associated with this command buffer.

      Operations keep their order within one fork, but forks merge in whatever order they finish. An entity queued in one fork must therefore never be named as the parent of an entity queued in another. Queue both in the same fork.

      Returns:
      the forked CommandBuffer instance from the associated store.
    • mergeParallel

      public void mergeParallel(@Nonnull CommandBuffer<ECS_TYPE> commandBuffer)
      Merges this command buffer back into the buffer it was forked from.
      Parameters:
      commandBuffer - The command buffer that this command buffer was forked from.
    • setThread

      public boolean setThread()
      Called to set the thread of this command buffer to the current thread.
      Returns:
      true to indicate that the thread was set successfully.
    • validateEmpty

      public void validateEmpty()
      Attempts to validate whether the queue is empty, throwing an assertion if it is not.