Giter VIP home page Giter VIP logo

Comments (3)

skelitheprogrammer avatar skelitheprogrammer commented on May 25, 2024

Is it really worth removing the Command Buffer?
Referring to the explanation of Command Buffer, there is a desire, on the contrary, to make it one of the root things of Arch. In other ecs libraries, Command Buffer analogues are a plug for the multithreading problem, which is not excluded with Arch. They look like they were made from the side.

Is World really supposed to have operations to interact with Entity (Add/Set/Remove Component. Maybe even Create?)? Maybe this should be the area of responsibility of Command Buffer, and World should have Extension functionality?

If you look at the same Wikipedia, then in the terminology there is nothing about World, Command Buffer. These are convenient tools for working with ECS pattern (World - entity hub/center/storage; Command Buffer - operation recorder). If you follow the path of lightweight and performance, then you can go very deep, which will create more problems (for example, create common World interface and put World in a separate package, like concrete implementation).

What if, the command buffer will work under the hood (not forgetting the ability to create your own instances), leaving the same extension methods

from arch.

jzapdot avatar jzapdot commented on May 25, 2024

It seems like CommandBuffers are currently the best way to make structural changes in entity queries in Arch. Nearly all of my systems execute query logic akin to this:

World.Query(_queryDescription, entity =>
{
    // Do work to stage adding/removing components or creating/destroying entities by using a command buffer.
});

// Effect all changes by playing back the command buffer
_commandBuffer.Playback();

Are there reasonable or better alternatives to this type of design pattern? If not, it seems like it would be hard to justify extracting them as an optional feature.

from arch.

skelitheprogrammer avatar skelitheprogrammer commented on May 25, 2024

What if we re-imagine Command Buffer?

We will have an IBufferCommand interface whose instances will be stored inside CommandBuffer and executed continuously.

public interface IBufferCommand
{
    void Execute();
}

public sealed partial class CommandBuffer : IDisposable
{
    private readonly List<IBufferCommand> _commands = new(); //or FIFO structure

    public void AddCommand(IBufferCommand command)
    {
        _commands.Add(command);
    }

    public void Playback(bool reset = true)
    {
        lock (this)
        {
            foreach (var item in _commands)
            {
                item.Execute();
            }

            if (reset)
            {
                Reset();
            }
        }
    }

    public void Reset()
    {
        _commands.Clear();
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

This way we can encapsulate commands (Create/Destroy/Set/Add) in their own implementations and so can create custom commands to integrate them into the flow.

We can create a CreateEntityDeferredCommand that will do the same logic as the current CommandBuffer.Create(types).

public readonly struct CreateEntityDeferredCommand: IBufferCommand
{
    private readonly World _world;

    private readonly ComponentType[] _types;

    private readonly object[] _components;

    public CreateEntityCommand(World world, ComponentType[] types, object[] components) : this()
    {
        _world = world;
        _types = types;
        _components = components;
    }


    public void Execute()
    {
        _world.Create(_types).SetRange(_components);
    }
}

and instead of buffer.AddCommand(new CreateEntityDeferredCommand(...)) we can make some builder struct that allows the user to specify components using a fluent api. With this we can create an extension method to wrap everything in a nice form.

public static partial class CommandBufferExtensions
{
  public static CreateEntityDeferredBuilder Create(this CommandBuffer buffer, World world, in ComponentType[] types)
  {
     CreateEntityDeferredBuilder builder = new(world, types);
     buffer.AddCommand(builder); //or some better place to add command
     return builder;
  }
}
buffer.Create(world, types).Set(C1).Set(C2);

buffer.Set(someActualEntity, C1);
buffer.Add(someActualEntity, C2);
//or maybe wrap up with some api to create chain of modifications on a particular entity at the time

buffer.Remove<C1>(someActualEntity);
buffer.Destroy(someActualEntity)

buffer.Playback();

The same is true for other commands.

Thus, we can move the CommandBuffer to the Extended repo because it no longer applies only to the core. The user can add their own behavior to synchronize with deferred execution.

UPD:
Made a branch where I will implement something similliar

from arch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.