store entity state + some garbage optimizations
parent
be95e80265
commit
190d1413ca
|
@ -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<int>(set.Count);
|
||||
set.Save(setState);
|
||||
state.FilterStates[signature] = setState;
|
||||
if (!state.FilterStates.ContainsKey(signature))
|
||||
{
|
||||
state.FilterStates[signature] = new IndexableSetState<int>(set.Count);
|
||||
}
|
||||
set.Save(state.FilterStates[signature]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<int> availableIDs = new Stack<int>();
|
||||
private readonly HashSet<int> availableIDHash = new HashSet<int>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
internal class IDStorage
|
||||
{
|
||||
private int nextID = 0;
|
||||
|
||||
private readonly Stack<int> availableIDs = new Stack<int>();
|
||||
private readonly HashSet<int> availableIDHash = new HashSet<int>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
public class ComponentDepotState
|
||||
internal class ComponentDepotState
|
||||
{
|
||||
public Dictionary<Type, ComponentStorageState> StorageStates = new Dictionary<Type, ComponentStorageState>();
|
||||
public Dictionary<FilterSignature, IndexableSetState<int>> FilterStates = new Dictionary<FilterSignature, IndexableSetState<int>>();
|
|
@ -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<int, int> EntityIdToStorageIndex;
|
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
internal class EntityStorageState
|
||||
{
|
||||
public int NextID;
|
||||
public List<int> availableIDs = new List<int>();
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
public class IndexableSetState<T> where T : unmanaged
|
||||
internal class IndexableSetState<T> where T : unmanaged
|
||||
{
|
||||
public int Count;
|
||||
public Dictionary<T, int> Indices;
|
|
@ -0,0 +1,14 @@
|
|||
namespace MoonTools.ECS
|
||||
{
|
||||
public class WorldState
|
||||
{
|
||||
internal ComponentDepotState ComponentDepotState;
|
||||
internal EntityStorageState EntityStorageState;
|
||||
|
||||
public WorldState()
|
||||
{
|
||||
ComponentDepotState = new ComponentDepotState();
|
||||
EntityStorageState = new EntityStorageState();
|
||||
}
|
||||
}
|
||||
}
|
17
src/World.cs
17
src/World.cs
|
@ -32,16 +32,21 @@
|
|||
ComponentDepot.DisableSerialization<TComponent>();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue