diff --git a/src/ComponentDepot.cs b/src/ComponentDepot.cs index 4c063ea..d5cb094 100644 --- a/src/ComponentDepot.cs +++ b/src/ComponentDepot.cs @@ -221,36 +221,31 @@ namespace MoonTools.ECS TypesWithDisabledSerialization.Add(typeof(TComponent)); } - public ComponentDepotState CreateState() - { - return new ComponentDepotState(); - } - public void Serialize(ComponentDepotState state) { - // FIXME: this is creating garbage - state.StorageStates.Clear(); foreach (var (type, storage) in storages) { - // FIXME: we could cache this if (!TypesWithDisabledSerialization.Contains(type)) { - var storageState = storage.CreateState(); - storage.Serialize(storageState); - state.StorageStates.Add(type, storageState); + if (!state.StorageStates.ContainsKey(type)) + { + state.StorageStates.Add(type, storage.CreateState()); + } + + storage.Serialize(state.StorageStates[type]); } } - // FIXME: this is creating garbage - state.FilterStates.Clear(); foreach (var (signature, set) in filterSignatureToEntityIDs) { // FIXME: we could cache this if (!signature.Included.Overlaps(TypesWithDisabledSerialization) && !signature.Excluded.Overlaps(TypesWithDisabledSerialization)) { - var setState = new IndexableSetState(set.Count); - set.Save(setState); - state.FilterStates[signature] = setState; + if (!state.FilterStates.ContainsKey(signature)) + { + state.FilterStates[signature] = new IndexableSetState(set.Count); + } + set.Save(state.FilterStates[signature]); } } } diff --git a/src/EntityStorage.cs b/src/EntityStorage.cs index 5d48a49..6e598a4 100644 --- a/src/EntityStorage.cs +++ b/src/EntityStorage.cs @@ -1,22 +1,75 @@ -namespace MoonTools.ECS +using System.Collections.Generic; + +namespace MoonTools.ECS { internal class EntityStorage { - public IDStorage idStorage = new IDStorage(); + private int nextID = 0; + private readonly Stack availableIDs = new Stack(); + private readonly HashSet availableIDHash = new HashSet(); public Entity Create() { - return new Entity(idStorage.NextID()); + return new Entity(NextID()); } public bool Exists(in Entity entity) { - return idStorage.Taken(entity.ID); + return Taken(entity.ID); } public void Destroy(in Entity entity) { - idStorage.Release(entity.ID); + Release(entity.ID); + } + + public void Serialize(EntityStorageState state) + { + state.NextID = nextID; + state.availableIDs.Clear(); + foreach (var id in availableIDs) + { + state.availableIDs.Add(id); + } + } + + public void Deserialize(EntityStorageState state) + { + nextID = state.NextID; + availableIDs.Clear(); + availableIDHash.Clear(); + foreach (var id in state.availableIDs) + { + availableIDs.Push(id); + availableIDHash.Add(id); + } + } + + private int NextID() + { + if (availableIDs.Count > 0) + { + var id = availableIDs.Pop(); + availableIDHash.Remove(id); + return id; + } + else + { + var id = nextID; + nextID += 1; + return id; + } + } + + private bool Taken(int id) + { + return !availableIDHash.Contains(id) && id < nextID; + } + + private void Release(int id) + { + availableIDs.Push(id); + availableIDHash.Add(id); } } } diff --git a/src/IDStorage.cs b/src/IDStorage.cs deleted file mode 100644 index 93e17bf..0000000 --- a/src/IDStorage.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; - -namespace MoonTools.ECS -{ - internal class IDStorage - { - private int nextID = 0; - - private readonly Stack availableIDs = new Stack(); - private readonly HashSet availableIDHash = new HashSet(); - - public int NextID() - { - if (availableIDs.Count > 0) - { - var id = availableIDs.Pop(); - availableIDHash.Remove(id); - return id; - } - else - { - var id = nextID; - nextID += 1; - return id; - } - } - - public bool Taken(int id) - { - return !availableIDHash.Contains(id) && id < nextID; - } - - public void Release(int id) - { - availableIDs.Push(id); - availableIDHash.Add(id); - } - } -} diff --git a/src/ComponentDepotState.cs b/src/State/ComponentDepotState.cs similarity index 90% rename from src/ComponentDepotState.cs rename to src/State/ComponentDepotState.cs index b137f24..2370dc6 100644 --- a/src/ComponentDepotState.cs +++ b/src/State/ComponentDepotState.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace MoonTools.ECS { - public class ComponentDepotState + internal class ComponentDepotState { public Dictionary StorageStates = new Dictionary(); public Dictionary> FilterStates = new Dictionary>(); diff --git a/src/ComponentStorageState.cs b/src/State/ComponentStorageState.cs similarity index 89% rename from src/ComponentStorageState.cs rename to src/State/ComponentStorageState.cs index dfc3e52..131f83c 100644 --- a/src/ComponentStorageState.cs +++ b/src/State/ComponentStorageState.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; namespace MoonTools.ECS { - // for saving and loading component storage - public class ComponentStorageState + internal class ComponentStorageState { public int Count; public Dictionary EntityIdToStorageIndex; diff --git a/src/State/EntityStorageState.cs b/src/State/EntityStorageState.cs new file mode 100644 index 0000000..66363dc --- /dev/null +++ b/src/State/EntityStorageState.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace MoonTools.ECS +{ + internal class EntityStorageState + { + public int NextID; + public List availableIDs = new List(); + } +} diff --git a/src/IndexableSetState.cs b/src/State/IndexableSetState.cs similarity index 76% rename from src/IndexableSetState.cs rename to src/State/IndexableSetState.cs index 43b7b79..378b9de 100644 --- a/src/IndexableSetState.cs +++ b/src/State/IndexableSetState.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; -using System.Runtime.InteropServices; namespace MoonTools.ECS { - public class IndexableSetState where T : unmanaged + internal class IndexableSetState where T : unmanaged { public int Count; public Dictionary Indices; diff --git a/src/State/WorldState.cs b/src/State/WorldState.cs new file mode 100644 index 0000000..dd2728a --- /dev/null +++ b/src/State/WorldState.cs @@ -0,0 +1,14 @@ +namespace MoonTools.ECS +{ + public class WorldState + { + internal ComponentDepotState ComponentDepotState; + internal EntityStorageState EntityStorageState; + + public WorldState() + { + ComponentDepotState = new ComponentDepotState(); + EntityStorageState = new EntityStorageState(); + } + } +} diff --git a/src/World.cs b/src/World.cs index a5dbe81..7ad8c4a 100644 --- a/src/World.cs +++ b/src/World.cs @@ -32,16 +32,21 @@ ComponentDepot.DisableSerialization(); } - public ComponentDepotState Serialize() + public WorldState CreateState() { - var state = ComponentDepot.CreateState(); - ComponentDepot.Serialize(state); - return state; + return new WorldState(); } - public void Deserialize(ComponentDepotState state) + public void Serialize(WorldState state) { - ComponentDepot.Deserialize(state); + ComponentDepot.Serialize(state.ComponentDepotState); + EntityStorage.Serialize(state.EntityStorageState); + } + + public void Deserialize(WorldState state) + { + ComponentDepot.Deserialize(state.ComponentDepotState); + EntityStorage.Deserialize(state.EntityStorageState); } } }