initial serialization structure
parent
5243259acb
commit
2fc1b68f41
|
@ -231,6 +231,30 @@ namespace MoonTools.ECS
|
|||
filterSignatureToEntityIDs[filterSignature].Add(entityID);
|
||||
}
|
||||
|
||||
public ComponentDepotState CreateState()
|
||||
{
|
||||
return new ComponentDepotState();
|
||||
}
|
||||
|
||||
public void Serialize(ComponentDepotState state)
|
||||
{
|
||||
state.StorageStates.Clear();
|
||||
foreach (var (type, storage) in storages)
|
||||
{
|
||||
var storageState = storage.CreateState();
|
||||
storage.Serialize(storageState);
|
||||
state.StorageStates.Add(type, storageState);
|
||||
}
|
||||
}
|
||||
|
||||
public void Deserialize(ComponentDepotState state)
|
||||
{
|
||||
foreach (var (type, storageState) in state.StorageStates)
|
||||
{
|
||||
storages[type].Deserialize(storageState);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public IEnumerable<object> Debug_GetAllComponents(int entityID)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
public class ComponentDepotState
|
||||
{
|
||||
public Dictionary<Type, ComponentStorageState> StorageStates = new Dictionary<Type, ComponentStorageState>();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
|
@ -8,9 +9,11 @@ namespace MoonTools.ECS
|
|||
public abstract bool Has(int entityID);
|
||||
public abstract void Remove(int entityID);
|
||||
public abstract object Debug_Get(int entityID);
|
||||
public abstract ComponentStorageState CreateState();
|
||||
public abstract void Serialize(ComponentStorageState state);
|
||||
public abstract void Deserialize(ComponentStorageState state);
|
||||
}
|
||||
|
||||
// FIXME: we can probably get rid of this weird entity storage system by using filters
|
||||
internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : struct
|
||||
{
|
||||
private int nextID;
|
||||
|
@ -106,5 +109,37 @@ namespace MoonTools.ECS
|
|||
{
|
||||
return new Entity(entityIDs[0]);
|
||||
}
|
||||
|
||||
public override ComponentStorageState CreateState()
|
||||
{
|
||||
return ComponentStorageState.Create<TComponent>(nextID);
|
||||
}
|
||||
|
||||
public override void Serialize(ComponentStorageState serializedComponentStorage)
|
||||
{
|
||||
ReadOnlySpan<byte> entityIDBytes = MemoryMarshal.Cast<int, byte>(new ReadOnlySpan<int>(entityIDs, 0, nextID));
|
||||
entityIDBytes.CopyTo(serializedComponentStorage.EntityIDs);
|
||||
|
||||
ReadOnlySpan<byte> componentBytes = MemoryMarshal.Cast<TComponent, byte>(AllComponents());
|
||||
componentBytes.CopyTo(serializedComponentStorage.Components);
|
||||
|
||||
serializedComponentStorage.EntityIdToStorageIndex.Clear();
|
||||
foreach (var kvp in entityIDToStorageIndex)
|
||||
{
|
||||
serializedComponentStorage.EntityIdToStorageIndex[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(ComponentStorageState serializedComponentStorage)
|
||||
{
|
||||
serializedComponentStorage.EntityIDs.CopyTo(MemoryMarshal.Cast<int, byte>(entityIDs));
|
||||
serializedComponentStorage.Components.CopyTo(MemoryMarshal.Cast<TComponent, byte>(components));
|
||||
|
||||
entityIDToStorageIndex.Clear();
|
||||
foreach (var kvp in serializedComponentStorage.EntityIdToStorageIndex)
|
||||
{
|
||||
entityIDToStorageIndex[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
// for saving and loading component storage
|
||||
public class ComponentStorageState
|
||||
{
|
||||
public int Count;
|
||||
public Dictionary<int, int> EntityIdToStorageIndex;
|
||||
public byte[] EntityIDs;
|
||||
public byte[] Components;
|
||||
|
||||
public static ComponentStorageState Create<TComponent>(int count)
|
||||
{
|
||||
return new ComponentStorageState(
|
||||
count,
|
||||
count * Marshal.SizeOf<int>(),
|
||||
count * Marshal.SizeOf<TComponent>()
|
||||
);
|
||||
}
|
||||
|
||||
private ComponentStorageState(int count, int entityIDSize, int componentSize)
|
||||
{
|
||||
Count = count;
|
||||
EntityIdToStorageIndex = new Dictionary<int, int>(count);
|
||||
EntityIDs = new byte[entityIDSize];
|
||||
Components = new byte[componentSize];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,52 +5,43 @@ namespace MoonTools.ECS
|
|||
{
|
||||
public abstract class EntityComponentReader
|
||||
{
|
||||
internal EntityStorage EntityStorage;
|
||||
internal ComponentDepot ComponentDepot;
|
||||
internal RelationDepot RelationDepot;
|
||||
protected readonly World World;
|
||||
internal EntityStorage EntityStorage => World.EntityStorage;
|
||||
internal ComponentDepot ComponentDepot => World.ComponentDepot;
|
||||
internal RelationDepot RelationDepot => World.RelationDepot;
|
||||
protected FilterBuilder FilterBuilder => new FilterBuilder(ComponentDepot);
|
||||
|
||||
internal void RegisterEntityStorage(EntityStorage entityStorage)
|
||||
public EntityComponentReader(World world)
|
||||
{
|
||||
EntityStorage = entityStorage;
|
||||
World = world;
|
||||
}
|
||||
|
||||
internal void RegisterComponentDepot(ComponentDepot componentDepot)
|
||||
{
|
||||
ComponentDepot = componentDepot;
|
||||
}
|
||||
|
||||
internal void RegisterRelationDepot(RelationDepot relationDepot)
|
||||
{
|
||||
RelationDepot = relationDepot;
|
||||
}
|
||||
|
||||
protected ReadOnlySpan<TComponent> ReadComponents<TComponent>() where TComponent : struct
|
||||
protected ReadOnlySpan<TComponent> ReadComponents<TComponent>() where TComponent : unmanaged
|
||||
{
|
||||
return ComponentDepot.ReadComponents<TComponent>();
|
||||
}
|
||||
|
||||
protected bool Has<TComponent>(in Entity entity) where TComponent : struct
|
||||
protected bool Has<TComponent>(in Entity entity) where TComponent : unmanaged
|
||||
{
|
||||
return ComponentDepot.Has<TComponent>(entity.ID);
|
||||
}
|
||||
|
||||
protected bool Some<TComponent>() where TComponent : struct
|
||||
protected bool Some<TComponent>() where TComponent : unmanaged
|
||||
{
|
||||
return ComponentDepot.Some<TComponent>();
|
||||
}
|
||||
|
||||
protected ref readonly TComponent Get<TComponent>(in Entity entity) where TComponent : struct
|
||||
protected ref readonly TComponent Get<TComponent>(in Entity entity) where TComponent : unmanaged
|
||||
{
|
||||
return ref ComponentDepot.Get<TComponent>(entity.ID);
|
||||
}
|
||||
|
||||
protected ref readonly TComponent GetSingleton<TComponent>() where TComponent : struct
|
||||
protected ref readonly TComponent GetSingleton<TComponent>() where TComponent : unmanaged
|
||||
{
|
||||
return ref ComponentDepot.Get<TComponent>();
|
||||
}
|
||||
|
||||
protected Entity GetSingletonEntity<TComponent>() where TComponent : struct
|
||||
protected Entity GetSingletonEntity<TComponent>() where TComponent : unmanaged
|
||||
{
|
||||
return ComponentDepot.GetSingletonEntity<TComponent>();
|
||||
}
|
||||
|
@ -60,22 +51,22 @@ namespace MoonTools.ECS
|
|||
return EntityStorage.Exists(entity);
|
||||
}
|
||||
|
||||
protected IEnumerable<(Entity, Entity, TRelationKind)> Relations<TRelationKind>() where TRelationKind : struct
|
||||
protected IEnumerable<(Entity, Entity, TRelationKind)> Relations<TRelationKind>() where TRelationKind : unmanaged
|
||||
{
|
||||
return RelationDepot.Relations<TRelationKind>();
|
||||
}
|
||||
|
||||
protected bool Related<TRelationKind>(in Entity a, in Entity b) where TRelationKind : struct
|
||||
protected bool Related<TRelationKind>(in Entity a, in Entity b) where TRelationKind : unmanaged
|
||||
{
|
||||
return RelationDepot.Related<TRelationKind>(a.ID, b.ID);
|
||||
}
|
||||
|
||||
protected IEnumerable<(Entity, TRelationKind)> RelatedToA<TRelationKind>(in Entity entity) where TRelationKind : struct
|
||||
protected IEnumerable<(Entity, TRelationKind)> RelatedToA<TRelationKind>(in Entity entity) where TRelationKind : unmanaged
|
||||
{
|
||||
return RelationDepot.RelatedToA<TRelationKind>(entity.ID);
|
||||
}
|
||||
|
||||
protected IEnumerable<(Entity, TRelationKind)> RelatedToB<TRelationKind>(in Entity entity) where TRelationKind : struct
|
||||
protected IEnumerable<(Entity, TRelationKind)> RelatedToB<TRelationKind>(in Entity entity) where TRelationKind : unmanaged
|
||||
{
|
||||
return RelationDepot.RelatedToB<TRelationKind>(entity.ID);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
{
|
||||
public abstract class Renderer : EntityComponentReader
|
||||
{
|
||||
public Renderer(World world)
|
||||
{
|
||||
world.AddRenderer(this);
|
||||
}
|
||||
public Renderer(World world) : base(world) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,17 +5,9 @@ namespace MoonTools.ECS
|
|||
{
|
||||
public abstract class System : EntityComponentReader
|
||||
{
|
||||
internal MessageDepot MessageDepot;
|
||||
internal MessageDepot MessageDepot => World.MessageDepot;
|
||||
|
||||
internal void RegisterMessageDepot(MessageDepot messageDepot)
|
||||
{
|
||||
MessageDepot = messageDepot;
|
||||
}
|
||||
|
||||
public System(World world)
|
||||
{
|
||||
world.AddSystem(this);
|
||||
}
|
||||
public System(World world) : base(world) { }
|
||||
|
||||
public abstract void Update(TimeSpan delta);
|
||||
|
||||
|
@ -24,7 +16,7 @@ namespace MoonTools.ECS
|
|||
return EntityStorage.Create();
|
||||
}
|
||||
|
||||
protected void Set<TComponent>(in Entity entity, in TComponent component) where TComponent : struct
|
||||
protected void Set<TComponent>(in Entity entity, in TComponent component) where TComponent : unmanaged
|
||||
{
|
||||
#if DEBUG
|
||||
// check for use after destroy
|
||||
|
@ -36,52 +28,52 @@ namespace MoonTools.ECS
|
|||
ComponentDepot.Set<TComponent>(entity.ID, component);
|
||||
}
|
||||
|
||||
protected void Remove<TComponent>(in Entity entity) where TComponent : struct
|
||||
protected void Remove<TComponent>(in Entity entity) where TComponent : unmanaged
|
||||
{
|
||||
ComponentDepot.Remove<TComponent>(entity.ID);
|
||||
}
|
||||
|
||||
protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : struct
|
||||
protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : unmanaged
|
||||
{
|
||||
return MessageDepot.All<TMessage>();
|
||||
}
|
||||
|
||||
protected TMessage ReadMessage<TMessage>() where TMessage : struct
|
||||
protected TMessage ReadMessage<TMessage>() where TMessage : unmanaged
|
||||
{
|
||||
return MessageDepot.First<TMessage>();
|
||||
}
|
||||
|
||||
protected bool SomeMessage<TMessage>() where TMessage : struct
|
||||
protected bool SomeMessage<TMessage>() where TMessage : unmanaged
|
||||
{
|
||||
return MessageDepot.Some<TMessage>();
|
||||
}
|
||||
|
||||
protected IEnumerable<TMessage> ReadMessagesWithEntity<TMessage>(in Entity entity) where TMessage : struct, IHasEntity
|
||||
protected IEnumerable<TMessage> ReadMessagesWithEntity<TMessage>(in Entity entity) where TMessage : unmanaged, IHasEntity
|
||||
{
|
||||
return MessageDepot.WithEntity<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
protected ref readonly TMessage ReadMessageWithEntity<TMessage>(in Entity entity) where TMessage : struct, IHasEntity
|
||||
protected ref readonly TMessage ReadMessageWithEntity<TMessage>(in Entity entity) where TMessage : unmanaged, IHasEntity
|
||||
{
|
||||
return ref MessageDepot.FirstWithEntity<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
protected bool SomeMessageWithEntity<TMessage>(in Entity entity) where TMessage : struct, IHasEntity
|
||||
protected bool SomeMessageWithEntity<TMessage>(in Entity entity) where TMessage : unmanaged, IHasEntity
|
||||
{
|
||||
return MessageDepot.SomeWithEntity<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
protected void Send<TMessage>(in TMessage message) where TMessage : struct
|
||||
protected void Send<TMessage>(in TMessage message) where TMessage : unmanaged
|
||||
{
|
||||
MessageDepot.Add(message);
|
||||
}
|
||||
|
||||
protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : struct
|
||||
protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged
|
||||
{
|
||||
RelationDepot.Add<TRelationKind>(new Relation(entityA, entityB), relationData);
|
||||
}
|
||||
|
||||
protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : struct
|
||||
protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
|
||||
{
|
||||
RelationDepot.Remove<TRelationKind>(new Relation(entityA, entityB));
|
||||
}
|
||||
|
|
35
src/World.cs
35
src/World.cs
|
@ -2,25 +2,10 @@
|
|||
{
|
||||
public class World
|
||||
{
|
||||
private readonly EntityStorage EntityStorage = new EntityStorage();
|
||||
private readonly ComponentDepot ComponentDepot = new ComponentDepot();
|
||||
private readonly MessageDepot MessageDepot = new MessageDepot();
|
||||
private readonly RelationDepot RelationDepot = new RelationDepot();
|
||||
|
||||
internal void AddSystem(System system)
|
||||
{
|
||||
system.RegisterEntityStorage(EntityStorage);
|
||||
system.RegisterComponentDepot(ComponentDepot);
|
||||
system.RegisterMessageDepot(MessageDepot);
|
||||
system.RegisterRelationDepot(RelationDepot);
|
||||
}
|
||||
|
||||
internal void AddRenderer(Renderer renderer)
|
||||
{
|
||||
renderer.RegisterEntityStorage(EntityStorage);
|
||||
renderer.RegisterComponentDepot(ComponentDepot);
|
||||
renderer.RegisterRelationDepot(RelationDepot);
|
||||
}
|
||||
internal readonly EntityStorage EntityStorage = new EntityStorage();
|
||||
internal readonly ComponentDepot ComponentDepot = new ComponentDepot();
|
||||
internal readonly MessageDepot MessageDepot = new MessageDepot();
|
||||
internal readonly RelationDepot RelationDepot = new RelationDepot();
|
||||
|
||||
public Entity CreateEntity()
|
||||
{
|
||||
|
@ -41,5 +26,17 @@
|
|||
{
|
||||
MessageDepot.Clear();
|
||||
}
|
||||
|
||||
public ComponentDepotState Serialize()
|
||||
{
|
||||
var state = ComponentDepot.CreateState();
|
||||
ComponentDepot.Serialize(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
public void Deserialize(ComponentDepotState state)
|
||||
{
|
||||
ComponentDepot.Deserialize(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue