From b30923ade3f9e45c822345713e94055a80ba6e84 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sun, 6 Mar 2022 23:17:05 -0800 Subject: [PATCH] initial message system --- src/IHasEntity.cs | 6 ++++++ src/MessageDepot.cs | 39 +++++++++++++++++++++++++++++++++++++ src/MessageStorage.cs | 45 +++++++++++++++++++++++++++++++++++++++++++ src/System.cs | 20 +++++++++++++++++-- src/World.cs | 3 ++- 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 src/IHasEntity.cs create mode 100644 src/MessageDepot.cs create mode 100644 src/MessageStorage.cs diff --git a/src/IHasEntity.cs b/src/IHasEntity.cs new file mode 100644 index 0000000..ac186a8 --- /dev/null +++ b/src/IHasEntity.cs @@ -0,0 +1,6 @@ +namespace MoonTools.ECS; + +public interface IHasEntity +{ + Entity Entity { get; } +} diff --git a/src/MessageDepot.cs b/src/MessageDepot.cs new file mode 100644 index 0000000..a5a66e9 --- /dev/null +++ b/src/MessageDepot.cs @@ -0,0 +1,39 @@ +namespace MoonTools.ECS; + +internal class MessageDepot +{ + private Dictionary storages = new Dictionary(); + + private MessageStorage Lookup() where TMessage : struct + { + if (!storages.ContainsKey(typeof(TMessage))) + { + storages.Add(typeof(TMessage), new MessageStorage()); + } + + return storages[typeof(TMessage)] as MessageStorage; + } + + public void Add(in TMessage message) where TMessage : struct + { + Lookup().Add(message); + } + + public bool Some() where TMessage : struct + { + return Lookup().Some(); + } + + public ReadOnlySpan Read() where TMessage : struct + { + return Lookup().All(); + } + + public void Clear() + { + foreach (var storage in storages.Values) + { + storage.Clear(); + } + } +} diff --git a/src/MessageStorage.cs b/src/MessageStorage.cs new file mode 100644 index 0000000..bf180cc --- /dev/null +++ b/src/MessageStorage.cs @@ -0,0 +1,45 @@ +namespace MoonTools.ECS; + +internal abstract class MessageStorage +{ + public abstract void Clear(); +} + +internal class MessageStorage : MessageStorage where TMessage : struct +{ + private int count = 0; + private int capacity = 128; + private TMessage[] messages; + + public MessageStorage() + { + messages = new TMessage[capacity]; + } + + public void Add(in TMessage message) + { + if (count == capacity) + { + capacity *= 2; + Array.Resize(ref messages, capacity); + } + + messages[count] = message; + count += 1; + } + + public bool Some() + { + return count > 0; + } + + public ReadOnlySpan All() + { + return new ReadOnlySpan(messages, 0, count); + } + + public override void Clear() + { + count = 0; + } +} diff --git a/src/System.cs b/src/System.cs index 2610411..d9d71ec 100644 --- a/src/System.cs +++ b/src/System.cs @@ -2,8 +2,7 @@ public abstract class System : EntityComponentReader { - public abstract void Update(TimeSpan delta); - + internal MessageDepot MessageDepot; public FilterBuilder FilterBuilder => new FilterBuilder(ComponentDepot); public System(World world) @@ -11,6 +10,13 @@ public abstract class System : EntityComponentReader world.AddSystem(this); } + internal void RegisterMessageDepot(MessageDepot messageDepot) + { + MessageDepot = messageDepot; + } + + public abstract void Update(TimeSpan delta); + protected Entity CreateEntity() { return EntityStorage.Create(); @@ -26,6 +32,16 @@ public abstract class System : EntityComponentReader ComponentDepot.Remove(entity.ID); } + protected ReadOnlySpan ReadMessages() where TMessage : struct + { + return MessageDepot.Read(); + } + + protected bool SomeMessage() where TMessage : struct + { + return MessageDepot.Some(); + } + protected void Destroy(in Entity entity) { ComponentDepot.OnEntityDestroy(entity.ID); diff --git a/src/World.cs b/src/World.cs index acf0886..dc62926 100644 --- a/src/World.cs +++ b/src/World.cs @@ -4,14 +4,15 @@ public class World { private readonly List Systems = new List(); private readonly List Renderers = new List(); - private readonly List Filters = new List(); private EntityStorage EntityStorage { get; } = new EntityStorage(); private ComponentDepot ComponentDepot { get; } = new ComponentDepot(); + private MessageDepot MessageDepot { get; } = new MessageDepot(); internal void AddSystem(System system) { system.RegisterEntityStorage(EntityStorage); system.RegisterComponentDepot(ComponentDepot); + system.RegisterMessageDepot(MessageDepot); Systems.Add(system); }