-
-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Outsource features to Arch.Extended
#121
Comments
Is it really worth removing the Command Buffer? 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 |
It seems like
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. |
What if we re-imagine Command Buffer? We will have an 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 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 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 UPD: |
The newly introduced
Relationships
-Feature can be provided outside the core e.g. inArch.Extended
. The same goes with theCommandBuffer
and the newBuffers
in total.This would keep the core slim and more organized.
The text was updated successfully, but these errors were encountered: