Comments (3)
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.
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.
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)
- Mark classes as sealed
- BitSet can cause exceptions on certain platforms HOT 1
- EVENTS and PURE_ECS together is unsupported
- World should have an IsAlive for EntityReference HOT 1
- Component Lifecycle Query Filters
- Component adding/removing events are inconsistent HOT 1
- Broken example on wiki page Query techniques (Custom enumeration)
- Bug in JobScheduler makes Arch not close all job threads. HOT 2
- Is it normal for coimponents not being removed on the entities? HOT 2
- Event handling via generics instead of conditional compilation HOT 3
- Command Buffer without world in constructor HOT 2
- chunk.Has<T>() is possibly broken HOT 2
- Enabling `EVENTS` on other platforms HOT 9
- Remove auto reset from Command Buffer `PlayBack()` method HOT 5
- Disable entity? HOT 1
- IndexOutOfRangeException in SparseJaggedArray HOT 5
- Faster version "World.Get<T>(Entity entity)" HOT 3
- Adding components within inline query affects references to current components HOT 2
- Emotes keep playing when falling / teleporting
- Arch and Blazor webassembly
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arch.