diff --git a/ECS/DataStructures/TypeSafeFasterListForECS.cs b/ECS/DataStructures/TypeSafeFasterListForECS.cs index 161ecf4..4bca085 100644 --- a/ECS/DataStructures/TypeSafeFasterListForECS.cs +++ b/ECS/DataStructures/TypeSafeFasterListForECS.cs @@ -48,12 +48,21 @@ namespace Svelto.ECS.Internal { var index = this.Count; - AddRange(entityViewListValue as FasterList); + base.AddRange(entityViewListValue as FasterList); for (int i = index; i < Count; ++i) _mappedIndices[this[i].ID] = i; } + new public void Add(T entityView) + { + var index = this.Count; + + base.Add(entityView); + + _mappedIndices[entityView.ID] = index; + } + public void ReserveCapacity(int capacity) { if (this.ToArrayFast().Length < capacity) diff --git a/ECS/EnginesRootEntities.cs b/ECS/EnginesRootEntities.cs index 923c2bb..f9c3896 100644 --- a/ECS/EnginesRootEntities.cs +++ b/ECS/EnginesRootEntities.cs @@ -164,6 +164,45 @@ namespace Svelto.ECS InternalRemove(EntityDescriptorTemplate.Default.entityViewsToBuild, entityID, _groupEntityViewsDB[groupID]); } + void SwapEntityGroup(int entityID, int fromGroupID, int toGroupID) where T : IEntityDescriptor, new() + { + DesignByContract.Check.Require(fromGroupID != toGroupID, "can't move an entity to the same group where it already belongs to"); + + var entityViewBuilders = EntityDescriptorTemplate.Default.entityViewsToBuild; + int entityViewBuildersCount = entityViewBuilders.Length; + + for (int i = 0; i < entityViewBuildersCount; i++) + { + IEntityViewBuilder entityViewBuilder = entityViewBuilders[i]; + Type entityViewType = entityViewBuilder.GetEntityViewType(); + Dictionary dictionary = _groupEntityViewsDB[fromGroupID]; + + ITypeSafeList fromSafeList = dictionary[entityViewType]; + + Dictionary groupedEntityViewsTyped; + if (_groupEntityViewsDB.TryGetValue(toGroupID, out groupedEntityViewsTyped) == false) + { + groupedEntityViewsTyped = new Dictionary(); + + _groupEntityViewsDB.Add(toGroupID, groupedEntityViewsTyped); + } + + ITypeSafeList toSafeList; + + if (groupedEntityViewsTyped.TryGetValue(entityViewType, out toSafeList) == false) + { + toSafeList = fromSafeList.Create(); + } + + entityViewBuilder.MoveEntityView(entityID, fromSafeList, toSafeList); + + if (fromSafeList.UnorderedRemove(entityID) == false) + dictionary.Remove(entityViewType); + + if (dictionary.Count == 0) _groupEntityViewsDB.Remove(fromGroupID); + } + } + void InternalRemove(IEntityViewBuilder[] entityViewBuilders, int entityID, Dictionary entityViewsDB) { @@ -192,6 +231,13 @@ namespace Svelto.ECS void InternalRemove(IEntityViewBuilder[] entityViewBuilders, int entityID, int groupID, Dictionary entityViewsDB) + { + InternalRemoveFromDB(entityViewBuilders, entityID, groupID); + + InternalRemove(entityViewBuilders, entityID, entityViewsDB); + } + + void InternalRemoveFromDB(IEntityViewBuilder[] entityViewBuilders, int entityID, int groupID) { int entityViewBuildersCount = entityViewBuilders.Length; @@ -205,8 +251,6 @@ namespace Svelto.ECS if (dictionary.Count == 0) _groupEntityViewsDB.Remove(groupID); } - - InternalRemove(entityViewBuilders, entityID, entityViewsDB); } static void RemoveEntityViewFromEngines(Dictionary> entityViewEngines, @@ -297,6 +341,11 @@ namespace Svelto.ECS _weakReference.Target.RemoveEntity(entityID); } + public void SwapEntityGroup(int entityID, int fromGroupID, int toGroupID) where T : IEntityDescriptor, new() + { + _weakReference.Target.SwapEntityGroup(entityID, fromGroupID, toGroupID); + } + readonly DataStructures.WeakReference _weakReference; } diff --git a/ECS/EnginesRootSubmission.cs b/ECS/EnginesRootSubmission.cs index b51f3f2..894881a 100644 --- a/ECS/EnginesRootSubmission.cs +++ b/ECS/EnginesRootSubmission.cs @@ -89,9 +89,9 @@ namespace Svelto.ECS { foreach (var group in groupedEntityViewsToAdd) { - AddEntityViewsToTheDBAndSuitableEngines(group.Value, entityViewsDB); - AddEntityViewsToGroupDB(groupEntityViewsDB, @group); + + AddEntityViewsToTheDBAndSuitableEngines(group.Value, entityViewsDB); } } diff --git a/ECS/EntityDescriptorTemplate.cs b/ECS/EntityDescriptor.cs similarity index 98% rename from ECS/EntityDescriptorTemplate.cs rename to ECS/EntityDescriptor.cs index d917577..91e09aa 100644 --- a/ECS/EntityDescriptorTemplate.cs +++ b/ECS/EntityDescriptor.cs @@ -105,7 +105,7 @@ namespace Svelto.ECS.Internal } } - static IEntityView BuildEntityView(int entityID, Dictionary entityViewsByType, + internal static IEntityView BuildEntityView(int entityID, Dictionary entityViewsByType, Type entityViewType, IEntityViewBuilder entityViewBuilder) { ITypeSafeList entityViewsList; diff --git a/ECS/EntityViewBuilder.cs b/ECS/EntityViewBuilder.cs index 6b02a66..b512cf9 100644 --- a/ECS/EntityViewBuilder.cs +++ b/ECS/EntityViewBuilder.cs @@ -9,6 +9,7 @@ namespace Svelto.ECS ITypeSafeList Preallocate(ref ITypeSafeList list, int size); Type GetEntityViewType(); + void MoveEntityView(int entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList); } public class EntityViewBuilder : IEntityViewBuilder where EntityViewType : EntityView, new() @@ -42,6 +43,14 @@ namespace Svelto.ECS return _entityViewType; } + public void MoveEntityView(int entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList) + { + var fromCastedList = fromSafeList as TypeSafeFasterListForECSForClasses; + var toCastedList = toSafeList as TypeSafeFasterListForECSForClasses; + + toCastedList.Add(fromCastedList[entityID]); + } + readonly Type _entityViewType = typeof(EntityViewType); } @@ -77,6 +86,14 @@ namespace Svelto.ECS return _entityViewType; } + public void MoveEntityView(int entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList) + { + var fromCastedList = fromSafeList as TypeSafeFasterListForECSForStructs; + var toCastedList = toSafeList as TypeSafeFasterListForECSForStructs; + + toCastedList.Add(fromCastedList[entityID]); + } + readonly Type _entityViewType = typeof(EntityViewType); } } \ No newline at end of file diff --git a/ECS/IEnginesInterfaces.cs b/ECS/IEnginesInterfaces.cs index 1929ca9..fe0494b 100644 --- a/ECS/IEnginesInterfaces.cs +++ b/ECS/IEnginesInterfaces.cs @@ -16,11 +16,12 @@ namespace Svelto.ECS public interface IEntityFunctions { void RemoveEntity(int entityID, IRemoveEntityComponent removeInfo); - void RemoveEntity(int entityID) where T:IEntityDescriptor, new(); - + void RemoveMetaEntity(int metaEntityID) where T:IEntityDescriptor, new(); void RemoveEntityFromGroup(int entityID, int groupID) where T:IEntityDescriptor, new(); + + void SwapEntityGroup(int entityID, int fromGroupID, int toGroupID) where T : IEntityDescriptor, new(); } }