From fc7a000064d6ca73b078bfe8cf393fddb1afbe50 Mon Sep 17 00:00:00 2001 From: Laszlo Paillat Date: Sun, 19 Sep 2021 14:08:18 +0200 Subject: [PATCH] remove EntityCommandRecorder.CreateEntity method, see new WorldRecord type added EntityCommandRecorder.Record(World) method added WorldRecord type to record action on World --- documentation/NEXT_RELEASENOTES.txt | 7 ++ .../Command/EntityCommandRecorderTest.cs | 92 ++++++++++++++----- source/DefaultEcs/AoTHelper.cs | 3 +- .../Command/EntityCommandRecorder.cs | 83 +++++++---------- source/DefaultEcs/Command/EntityRecord.cs | 4 +- source/DefaultEcs/Command/WorldRecord.cs | 67 ++++++++++++++ .../Internal/Command/CommandType.cs | 24 ++--- .../DefaultEcs/Internal/Command/Commands.cs | 20 ++++ .../Internal/Command/ComponentCommands.cs | 25 +++-- .../DefaultEcs/Internal/Command/Executer.cs | 12 +++ .../Internal/Command/IComponentCommand.cs | 2 + .../Command/ManagedComponentCommand.cs | 7 ++ .../Command/UnmanagedComponentCommand.cs | 9 +- 13 files changed, 259 insertions(+), 96 deletions(-) create mode 100644 source/DefaultEcs/Command/WorldRecord.cs diff --git a/documentation/NEXT_RELEASENOTES.txt b/documentation/NEXT_RELEASENOTES.txt index d944fe22..ce96c4f4 100644 --- a/documentation/NEXT_RELEASENOTES.txt +++ b/documentation/NEXT_RELEASENOTES.txt @@ -1,3 +1,10 @@ +breaking changes: +remove EntityCommandRecorder.CreateEntity method, see new WorldRecord type + +--- + +added EntityCommandRecorder.Record(World) method +added WorldRecord type to record action on World added EntitySortedSet type (#113) added EntityQueryBuilder.AsSortedSet methods to create EntitySortedSet added AEntitySortedSetSystem type diff --git a/source/DefaultEcs.Test/Command/EntityCommandRecorderTest.cs b/source/DefaultEcs.Test/Command/EntityCommandRecorderTest.cs index 068fb046..4836e154 100644 --- a/source/DefaultEcs.Test/Command/EntityCommandRecorderTest.cs +++ b/source/DefaultEcs.Test/Command/EntityCommandRecorderTest.cs @@ -23,11 +23,11 @@ public NonBlittable(int id, object item) #region Tests [Fact] - public void CreateEntity_Should_throw_When_world_is_null() + public void Record_Should_throw_When_world_is_null() { using EntityCommandRecorder recorder = new(1024); - Check.ThatCode(() => recorder.CreateEntity(default)).Throws(); + Check.ThatCode(() => recorder.Record(default(World))).Throws(); } [Fact] @@ -36,17 +36,59 @@ public void CreateEntity_Should_create_an_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - recorder.CreateEntity(world); - recorder.CreateEntity(world); - recorder.CreateEntity(world); - recorder.CreateEntity(world); - recorder.CreateEntity(world); + WorldRecord record = recorder.Record(world); + + record.CreateEntity(); + record.CreateEntity(); + record.CreateEntity(); + record.CreateEntity(); + record.CreateEntity(); recorder.Execute(); Check.That(world.Count()).IsEqualTo(5); } + [Fact] + public void Set_Should_set_blittable_component_on_world() + { + using EntityCommandRecorder recorder = new(1024); + using World world = new(); + + recorder.Record(world).Set(); + + recorder.Execute(); + + Check.That(world.Get()).IsEqualTo(0); + } + + [Fact] + public void Set_Should_set_non_blittable_component_on_world() + { + using EntityCommandRecorder recorder = new(1024); + using World world = new(); + + recorder.Record(world).Set("kikoo"); + + recorder.Execute(); + + Check.That(world.Get()).IsEqualTo("kikoo"); + } + + [Fact] + public void Remove_Should_remove_component_from_world() + { + using EntityCommandRecorder recorder = new(1024); + using World world = new(); + + world.Set(42); + recorder.Record(world).Remove(); + + recorder.Execute(); + + Check.That(world.Has()).IsFalse(); + } + [Fact] public void Disable_Should_disable_recorded_entity() { @@ -69,7 +111,7 @@ public void Disable_Should_disable_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Disable(); recorder.Execute(); @@ -100,7 +142,7 @@ public void Enable_Should_enable_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Disable(); record.Enable(); @@ -131,7 +173,7 @@ public void Set_Should_set_blittable_component_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(true); recorder.Execute(); @@ -163,7 +205,7 @@ public void Set_Should_set_reference_component_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(o); recorder.Execute(); @@ -196,7 +238,7 @@ public void Set_Should_set_non_blittable_component_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(new NonBlittable(42, o)); recorder.Execute(); @@ -228,7 +270,7 @@ public void DisableT_Should_disable_component_of_type_T_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(true); record.Disable(); @@ -261,7 +303,7 @@ public void EnableT_Should_enable_component_of_type_T_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(true); record.Disable(); record.Enable(); @@ -294,7 +336,7 @@ public void Remove_Should_remove_component_on_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(true); record.Remove(); @@ -332,7 +374,7 @@ public void NotifyChanged_Should_change_component_on_created_entity() using World world = new(); using IDisposable changed = world.SubscribeComponentChanged((in Entity e, in bool _, in bool _) => result = e); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Set(true); record.NotifyChanged(); @@ -363,7 +405,7 @@ public void Dispose_Should_dispose_created_entity() using EntityCommandRecorder recorder = new(1024); using World world = new(); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.Dispose(); recorder.Execute(); @@ -398,7 +440,7 @@ public void SetSameAs_Should_set_same_as_on_created_entity() Entity reference = world.CreateEntity(); reference.Set(true); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.SetSameAs(recorder.Record(reference)); recorder.Execute(); @@ -416,7 +458,7 @@ public void SetSameAsWorld_Should_set_same_as_on_created_entity() world.Set(true); - EntityRecord record = recorder.CreateEntity(world); + EntityRecord record = recorder.Record(world).CreateEntity(); record.SetSameAsWorld(); recorder.Execute(); @@ -430,7 +472,7 @@ public void Should_work_in_multithread() using EntityCommandRecorder recorder = new(8, int.MaxValue); using World world = new(); - Enumerable.Range(0, 100000).AsParallel().ForAll(_ => recorder.CreateEntity(world)); + Enumerable.Range(0, 100000).AsParallel().ForAll(_ => recorder.Record(world).CreateEntity()); recorder.Execute(); @@ -465,12 +507,12 @@ public void Shoud_throw_When_no_more_space() Check.That(recorder.Capacity).IsEqualTo(8); Check.That(recorder.MaxCapacity).IsEqualTo(16); - recorder.CreateEntity(world); + recorder.Record(world).CreateEntity(); Check.That(recorder.Size).IsEqualTo(9); Check.That(recorder.Capacity).IsEqualTo(recorder.MaxCapacity); - Check.ThatCode(() => recorder.CreateEntity(world)).Throws(); + Check.ThatCode(() => recorder.Record(world).CreateEntity()).Throws(); } [Fact] @@ -479,7 +521,7 @@ public void Execute_Should_clear_recorded_command_after_executing() using EntityCommandRecorder recorder = new(); using World world = new(); - recorder.CreateEntity(world); + recorder.Record(world).CreateEntity(); Check.That(recorder.Size).IsNotZero(); @@ -500,7 +542,7 @@ public void Clear_Should_clear_recorded_command() using EntityCommandRecorder recorder = new(5, 10); using World world = new(); - recorder.CreateEntity(world); + recorder.Record(world).CreateEntity(); Check.That(recorder.Size).IsNotZero(); @@ -519,7 +561,7 @@ public void CopyTo_Should_throw_When_cloner_is_null() using EntityCommandRecorder recorder = new(1024); using World world = new(); - Check.ThatCode(() => recorder.CreateEntity(world).CopyTo(world, default)).Throws(); + Check.ThatCode(() => recorder.Record(world).CreateEntity().CopyTo(world, default)).Throws(); } [Fact] diff --git a/source/DefaultEcs/AoTHelper.cs b/source/DefaultEcs/AoTHelper.cs index b876c4c6..c7a892c5 100644 --- a/source/DefaultEcs/AoTHelper.cs +++ b/source/DefaultEcs/AoTHelper.cs @@ -54,7 +54,8 @@ public static void RegisterUnmanagedComponent() T value; UnmanagedComponentCommand.WriteComponent(default, (byte*)&value, default); - UnmanagedComponentCommand.SetComponent(entity, default, (byte*)&value); + UnmanagedComponentCommand.SetWorldComponent(world, default, (byte*)&value); + UnmanagedComponentCommand.SetEntityComponent(entity, default, (byte*)&value); } } } diff --git a/source/DefaultEcs/Command/EntityCommandRecorder.cs b/source/DefaultEcs/Command/EntityCommandRecorder.cs index 1af7041f..bbb87781 100644 --- a/source/DefaultEcs/Command/EntityCommandRecorder.cs +++ b/source/DefaultEcs/Command/EntityCommandRecorder.cs @@ -88,23 +88,6 @@ public EntityCommandRecorder() #region Methods - private void WriteCommand(int offset, in T command) - where T : unmanaged - { - _lockObject?.EnterReadLock(); - try - { - fixed (byte* memory = _memory) - { - *(T*)(memory + offset) = command; - } - } - finally - { - _lockObject?.ExitReadLock(); - } - } - private int ReserveNextCommand(int commandSize) { static void Throw() => throw new InvalidOperationException("CommandBuffer is full."); @@ -139,25 +122,45 @@ private int ReserveNextCommand(int commandSize) return commandOffset; } - internal void WriteCommand(in T command) where T : unmanaged => WriteCommand(ReserveNextCommand(sizeof(T)), command); + internal int WriteCommand(in T command) where T : unmanaged + { + int offset = ReserveNextCommand(sizeof(T)); - internal void WriteSetCommand(int entityOffset, in T component) + _lockObject?.EnterReadLock(); + try + { + fixed (byte* memory = _memory) + { + *(T*)(memory + offset) = command; + } + } + finally + { + _lockObject?.ExitReadLock(); + } + + return offset; + } + + internal int WriteComponentCommand(in TCommand command, in TComponent component) where TCommand : unmanaged { - int offset = ReserveNextCommand(sizeof(EntityOffsetComponentCommand) + ComponentCommands.ComponentCommand.SizeOfT); + int offset = ReserveNextCommand(sizeof(TCommand) + ComponentCommands.ComponentCommand.SizeOfT); _lockObject?.EnterReadLock(); try { fixed (byte* memory = _memory) { - *(EntityOffsetComponentCommand*)(memory + offset) = new EntityOffsetComponentCommand(CommandType.Set, ComponentCommands.ComponentCommand.Index, entityOffset); - ComponentCommands.ComponentCommand.WriteComponent(_objects, memory + offset + sizeof(EntityOffsetComponentCommand), component); + *(TCommand*)(memory + offset) = command; + ComponentCommands.ComponentCommand.WriteComponent(_objects, memory + offset + sizeof(TCommand), component); } } finally { _lockObject?.ExitReadLock(); } + + return offset; } internal void WriteCloneCommand(int sourceOffset, int targetOffset, ComponentCloner cloner) @@ -165,7 +168,7 @@ internal void WriteCloneCommand(int sourceOffset, int targetOffset, ComponentClo int clonerIndex; lock (_objects) { - clonerIndex = _objects.Count; + clonerIndex = _objects.Count; _objects.Add(cloner); } @@ -173,38 +176,20 @@ internal void WriteCloneCommand(int sourceOffset, int targetOffset, ComponentClo } /// - /// Gives an to record action on the given . - /// This command takes 9 bytes. + /// Gives an to record action on the given . /// - /// The used to record action on the given . - /// The used to record actions on the given . - /// Command buffer is full. - public EntityRecord Record(in Entity entity) - { - int offset = ReserveNextCommand(sizeof(EntityCommand)); - - WriteCommand(offset, new EntityCommand(CommandType.Entity, entity)); - - return new EntityRecord(this, offset + sizeof(CommandType)); - } + /// The to record action for. + /// The used to record actions on the given . + public WorldRecord Record(World world) => new(this, world ?? throw new ArgumentNullException(nameof(world))); /// - /// Records the creation of an on a and returns an to record action on it. + /// Gives an to record action on the given . /// This command takes 9 bytes. /// - /// The on which the entity need to be created. - /// The used to record actions on the later created . + /// The to record action for. + /// The used to record actions on the given . /// Command buffer is full. - public EntityRecord CreateEntity(World world) - { - if (world is null) throw new ArgumentNullException(nameof(world)); - - int offset = ReserveNextCommand(sizeof(EntityCommand)); - - WriteCommand(offset, new EntityCommand(CommandType.CreateEntity, new Entity(world.WorldId))); - - return new EntityRecord(this, offset + sizeof(CommandType)); - } + public EntityRecord Record(in Entity entity) => new(this, WriteCommand(new EntityCommand(CommandType.Entity, entity)) + sizeof(CommandType)); /// /// Executes all recorded commands and clears those commands. diff --git a/source/DefaultEcs/Command/EntityRecord.cs b/source/DefaultEcs/Command/EntityRecord.cs index 0d742537..9a362d0a 100644 --- a/source/DefaultEcs/Command/EntityRecord.cs +++ b/source/DefaultEcs/Command/EntityRecord.cs @@ -66,7 +66,7 @@ internal EntityRecord(EntityCommandRecorder recorder, int offset) /// The type of the component. /// The value of the component. /// Command buffer is full. - public void Set(in T component) => _recorder.WriteSetCommand(_offset, component); + public void Set(in T component) => _recorder.WriteComponentCommand(new EntityOffsetComponentCommand(CommandType.Set, ComponentCommands.ComponentCommand.Index, _offset), component); /// /// Sets the value of the component of type to its default value on the corresponding . @@ -119,7 +119,7 @@ internal EntityRecord(EntityCommandRecorder recorder, int offset) /// or was null. public EntityRecord CopyTo(World world, ComponentCloner cloner) { - EntityRecord copy = _recorder.CreateEntity(world); + EntityRecord copy = _recorder.Record(world).CreateEntity(); _recorder.WriteCloneCommand(_offset, copy._offset, cloner ?? throw new ArgumentNullException(nameof(cloner))); diff --git a/source/DefaultEcs/Command/WorldRecord.cs b/source/DefaultEcs/Command/WorldRecord.cs new file mode 100644 index 00000000..d4c5810e --- /dev/null +++ b/source/DefaultEcs/Command/WorldRecord.cs @@ -0,0 +1,67 @@ +using System; +using DefaultEcs.Internal.Command; + +namespace DefaultEcs.Command +{ + /// + /// Represents a on which to create commands to record in a . + /// + public readonly ref struct WorldRecord + { + #region Fields + + private readonly EntityCommandRecorder _recorder; + private readonly short _worldId; + + #endregion + + #region Initialisation + + internal WorldRecord(EntityCommandRecorder recorder, World world) + { + _recorder = recorder; + _worldId = world.WorldId; + } + + #endregion + + #region Methods + + /// + /// Records the creation of an on a and returns an to record action on it. + /// This command takes 9 bytes. + /// + /// The used to record actions on the later created . + /// Command buffer is full. + public EntityRecord CreateEntity() => new(_recorder, _recorder.WriteCommand(new EntityCommand(CommandType.CreateEntity, new Entity(_worldId))) + sizeof(CommandType)); + + /// + /// Sets the value of the component of type on the corresponding . + /// For a blittable component, this command takes 7 bytes + the size of the component. + /// For non blittable component, this command takes 11 bytes and may cause some allocation because of boxing on struct component type. + /// + /// The type of the component. + /// The value of the component. + /// Command buffer is full. + public void Set(in T component) => _recorder.WriteComponentCommand(new WorldCommand(CommandType.WorldSet, ComponentCommands.ComponentCommand.Index, _worldId), component); + + /// + /// Sets the value of the component of type to its default value on the corresponding . + /// For a blittable component, this command takes 7 bytes + the size of the component. + /// For non blittable component, this command takes 11 bytes and may cause some allocation because of boxing on struct component type. + /// + /// The type of the component. + /// Command buffer is full. + public void Set() => Set(default); + + /// + /// Removes the component of type on the corresponding . + /// This command takes 7 bytes. + /// + /// The type of the component. + /// Command buffer is full. + public void Remove() => _recorder.WriteCommand(new WorldCommand(CommandType.WorldRemove, ComponentCommands.ComponentCommand.Index, _worldId)); + + #endregion + } +} diff --git a/source/DefaultEcs/Internal/Command/CommandType.cs b/source/DefaultEcs/Internal/Command/CommandType.cs index 9d94ccf5..e05a5116 100644 --- a/source/DefaultEcs/Internal/Command/CommandType.cs +++ b/source/DefaultEcs/Internal/Command/CommandType.cs @@ -4,16 +4,18 @@ internal enum CommandType : byte { Entity = 0, CreateEntity = 1, - Enable = 2, - Disable = 3, - EnableT = 4, - DisableT = 5, - Set = 6, - SetSameAs = 7, - SetSameAsWorld = 8, - Remove = 9, - NotifyChanged = 10, - Clone = 11, - Dispose = 12 + WorldSet = 2, + WorldRemove = 3, + Enable = 4, + Disable = 5, + EnableT = 6, + DisableT = 7, + Set = 8, + SetSameAs = 9, + SetSameAsWorld = 10, + Remove = 11, + NotifyChanged = 12, + Clone = 13, + Dispose = 14 } } diff --git a/source/DefaultEcs/Internal/Command/Commands.cs b/source/DefaultEcs/Internal/Command/Commands.cs index 2c70c1e1..ed8924a6 100644 --- a/source/DefaultEcs/Internal/Command/Commands.cs +++ b/source/DefaultEcs/Internal/Command/Commands.cs @@ -2,6 +2,26 @@ namespace DefaultEcs.Internal.Command { + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct WorldCommand + { + [FieldOffset(0)] + public CommandType CommandType; + + [FieldOffset(1)] + public readonly int ComponentIndex; + + [FieldOffset(5)] + public short WorldId; + + public WorldCommand(CommandType commandType, int componentIndex, short worldId) + { + CommandType = commandType; + ComponentIndex = componentIndex; + WorldId = worldId; + } + } + [StructLayout(LayoutKind.Explicit, Pack = 1)] internal struct EntityCommand { diff --git a/source/DefaultEcs/Internal/Command/ComponentCommands.cs b/source/DefaultEcs/Internal/Command/ComponentCommands.cs index 0417abf8..1d57308b 100644 --- a/source/DefaultEcs/Internal/Command/ComponentCommands.cs +++ b/source/DefaultEcs/Internal/Command/ComponentCommands.cs @@ -11,14 +11,17 @@ internal static class ComponentCommands public unsafe delegate void WriteComponent(List objects, byte* memory, in T component); - public unsafe delegate int SetComponent(in Entity entity, List objects, byte* memory); + public unsafe delegate int WorldSetComponent(World world, List objects, byte* memory); + + public unsafe delegate int EntitySetComponent(in Entity entity, List objects, byte* memory); public unsafe class ComponentCommand : IComponentCommand { #region Fields private static readonly WriteComponent _writeComponentAction; - private static readonly SetComponent _setAction; + private static readonly WorldSetComponent _worldSetAction; + private static readonly EntitySetComponent _entitySetAction; [SuppressMessage("Design", "RCS1158:Static member in generic type should use a type parameter.")] public static readonly int Index; @@ -46,16 +49,20 @@ static ComponentCommand() _writeComponentAction = (WriteComponent)typeInfo .GetDeclaredMethod(nameof(UnmanagedComponentCommand.WriteComponent)) .CreateDelegate(typeof(WriteComponent)); - _setAction = (SetComponent)typeInfo - .GetDeclaredMethod(nameof(UnmanagedComponentCommand.SetComponent)) - .CreateDelegate(typeof(SetComponent)); + _worldSetAction = (WorldSetComponent)typeInfo + .GetDeclaredMethod(nameof(UnmanagedComponentCommand.SetWorldComponent)) + .CreateDelegate(typeof(WorldSetComponent)); + _entitySetAction = (EntitySetComponent)typeInfo + .GetDeclaredMethod(nameof(UnmanagedComponentCommand.SetEntityComponent)) + .CreateDelegate(typeof(EntitySetComponent)); } else { SizeOfT = sizeof(int); _writeComponentAction = ManagedComponentCommand.WriteComponent; - _setAction = ManagedComponentCommand.Set; + _worldSetAction = ManagedComponentCommand.Set; + _entitySetAction = ManagedComponentCommand.Set; } } @@ -69,11 +76,15 @@ static ComponentCommand() #region IComponentCommand + public int Set(World world, List objects, byte* memory) => _worldSetAction(world, objects, memory); + + public void Remove(World world) => world.Remove(); + public void Enable(in Entity entity) => entity.Enable(); public void Disable(in Entity entity) => entity.Disable(); - public int Set(in Entity entity, List objects, byte* memory) => _setAction(entity, objects, memory); + public int Set(in Entity entity, List objects, byte* memory) => _entitySetAction(entity, objects, memory); public void SetSameAs(in Entity entity, in Entity reference) => entity.SetSameAs(reference); diff --git a/source/DefaultEcs/Internal/Command/Executer.cs b/source/DefaultEcs/Internal/Command/Executer.cs index 9099032c..6b42f86a 100644 --- a/source/DefaultEcs/Internal/Command/Executer.cs +++ b/source/DefaultEcs/Internal/Command/Executer.cs @@ -25,6 +25,18 @@ public static unsafe void Execute(byte[] memory, int commandLength, List commandSize = sizeof(EntityCommand); break; + case CommandType.WorldSet: + WorldCommand* worldCommand = (WorldCommand*)commands; + commandSize = sizeof(WorldCommand); + commandSize += ComponentCommands.GetCommand(worldCommand->ComponentIndex).Set(World.Worlds[worldCommand->WorldId], objects, commands + sizeof(EntityOffsetComponentCommand)); + break; + + case CommandType.WorldRemove: + worldCommand = (WorldCommand*)commands; + ComponentCommands.GetCommand(worldCommand->ComponentIndex).Remove(World.Worlds[worldCommand->WorldId]); + commandSize = sizeof(WorldCommand); + break; + case CommandType.Enable: ((Entity*)(memoryP + ((EntityOffsetCommand*)commands)->EntityOffset))->Enable(); commandSize = sizeof(EntityOffsetCommand); diff --git a/source/DefaultEcs/Internal/Command/IComponentCommand.cs b/source/DefaultEcs/Internal/Command/IComponentCommand.cs index 0dba0ad7..08d12b67 100644 --- a/source/DefaultEcs/Internal/Command/IComponentCommand.cs +++ b/source/DefaultEcs/Internal/Command/IComponentCommand.cs @@ -4,6 +4,8 @@ namespace DefaultEcs.Internal.Command { internal unsafe interface IComponentCommand { + int Set(World world, List objects, byte* memory); + void Remove(World world); void Enable(in Entity entity); void Disable(in Entity entity); int Set(in Entity entity, List objects, byte* memory); diff --git a/source/DefaultEcs/Internal/Command/ManagedComponentCommand.cs b/source/DefaultEcs/Internal/Command/ManagedComponentCommand.cs index 02a48fdb..04c18af7 100644 --- a/source/DefaultEcs/Internal/Command/ManagedComponentCommand.cs +++ b/source/DefaultEcs/Internal/Command/ManagedComponentCommand.cs @@ -13,6 +13,13 @@ public static void WriteComponent(List objects, byte* data, in T compone } } + public static int Set(World world, List objects, byte* memory) + { + world.Set((T)objects[*(int*)memory]); + + return sizeof(int); + } + public static int Set(in Entity entity, List objects, byte* memory) { entity.Set((T)objects[*(int*)memory]); diff --git a/source/DefaultEcs/Internal/Command/UnmanagedComponentCommand.cs b/source/DefaultEcs/Internal/Command/UnmanagedComponentCommand.cs index a69ce566..bc64db11 100644 --- a/source/DefaultEcs/Internal/Command/UnmanagedComponentCommand.cs +++ b/source/DefaultEcs/Internal/Command/UnmanagedComponentCommand.cs @@ -11,7 +11,14 @@ internal sealed unsafe class UnmanagedComponentCommand public static void WriteComponent(List _, byte* data, in T component) => *(T*)data = component; - public static int SetComponent(in Entity entity, List _, byte* memory) + public static int SetWorldComponent(World world, List _, byte* memory) + { + world.Set(*(T*)memory); + + return SizeOfT; + } + + public static int SetEntityComponent(in Entity entity, List _, byte* memory) { entity.Set(*(T*)memory);