From 6858ec1b0fdd5c7505f5ce45e72235219ceead54 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 12 Mar 2021 08:25:25 +0000 Subject: [PATCH] Mega Refactor (#20) Co-Authored-By: cosmonaut Co-Committed-By: cosmonaut --- encompass-cs/Attributes/Adds.cs | 16 +++ encompass-cs/Attributes/Receives.cs | 11 -- encompass-cs/Attributes/Sends.cs | 11 -- encompass-cs/Collections/MessageStore.cs | 22 +-- .../Collections/TypedComponentStore.cs | 3 +- encompass-cs/Collections/TypedMessageStore.cs | 2 +- encompass-cs/ComponentManager.cs | 13 +- encompass-cs/DrawLayerManager.cs | 132 ------------------ encompass-cs/Engine.cs | 68 ++++----- encompass-cs/Engines/Spawner.cs | 2 +- .../Exceptions/IllegalSendTypeException.cs | 12 -- encompass-cs/IMessage.cs | 7 - encompass-cs/Interfaces/IComponent.cs | 4 - encompass-cs/Interfaces/IDrawableComponent.cs | 7 - encompass-cs/MessageManager.cs | 18 +-- encompass-cs/RenderManager.cs | 38 +---- encompass-cs/Renderer.cs | 20 +-- encompass-cs/Renderers/GeneralRenderer.cs | 11 -- encompass-cs/Renderers/OrderedRenderer.cs | 18 --- encompass-cs/UberEngine.cs | 7 +- encompass-cs/UberRenderer.cs | 4 +- encompass-cs/WorldBuilder.cs | 128 ++++++----------- test/ComponentTest.cs | 16 +-- test/EngineTest.cs | 22 +-- test/OrderedRendererTest.cs | 109 --------------- ...GeneralRendererTest.cs => RendererTest.cs} | 8 +- test/SpawnerTest.cs | 4 +- test/WorldBuilderTest.cs | 112 +++------------ test/WorldTest.cs | 81 ----------- 29 files changed, 188 insertions(+), 718 deletions(-) create mode 100644 encompass-cs/Attributes/Adds.cs delete mode 100644 encompass-cs/DrawLayerManager.cs delete mode 100644 encompass-cs/Exceptions/IllegalSendTypeException.cs delete mode 100644 encompass-cs/IMessage.cs delete mode 100644 encompass-cs/Interfaces/IComponent.cs delete mode 100644 encompass-cs/Interfaces/IDrawableComponent.cs delete mode 100644 encompass-cs/Renderers/GeneralRenderer.cs delete mode 100644 encompass-cs/Renderers/OrderedRenderer.cs delete mode 100644 test/OrderedRendererTest.cs rename test/{GeneralRendererTest.cs => RendererTest.cs} (88%) delete mode 100644 test/WorldTest.cs diff --git a/encompass-cs/Attributes/Adds.cs b/encompass-cs/Attributes/Adds.cs new file mode 100644 index 0000000..1c71ae6 --- /dev/null +++ b/encompass-cs/Attributes/Adds.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Encompass +{ + [AttributeUsage(AttributeTargets.Class)] + public class Adds : Attribute + { + public readonly HashSet addTypes; + + public Adds(params Type[] addTypes) + { + this.addTypes = new HashSet(addTypes); + } + } +} diff --git a/encompass-cs/Attributes/Receives.cs b/encompass-cs/Attributes/Receives.cs index 79d4b66..865e399 100644 --- a/encompass-cs/Attributes/Receives.cs +++ b/encompass-cs/Attributes/Receives.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using Encompass.Exceptions; namespace Encompass { @@ -12,15 +10,6 @@ namespace Encompass public Receives(params Type[] receiveTypes) { - foreach (var receiveType in receiveTypes) - { - var isMessage = receiveType.GetInterfaces().Contains(typeof(IMessage)); - if (!isMessage) - { - throw new IllegalSendTypeException("{0} must be a Message", receiveType.Name); - } - } - ReceiveTypes = new HashSet(receiveTypes); } } diff --git a/encompass-cs/Attributes/Sends.cs b/encompass-cs/Attributes/Sends.cs index 8fbacd3..d5a582a 100644 --- a/encompass-cs/Attributes/Sends.cs +++ b/encompass-cs/Attributes/Sends.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using Encompass.Exceptions; namespace Encompass { @@ -12,15 +10,6 @@ namespace Encompass public Sends(params Type[] sendTypes) { - foreach (var sendType in sendTypes) - { - var isMessage = sendType.GetInterfaces().Contains(typeof(IMessage)); - if (!isMessage) - { - throw new IllegalSendTypeException("{0} must be a Message", sendType.Name); - } - } - this.SendTypes = new HashSet(sendTypes); } } diff --git a/encompass-cs/Collections/MessageStore.cs b/encompass-cs/Collections/MessageStore.cs index 196dc7f..1949b13 100644 --- a/encompass-cs/Collections/MessageStore.cs +++ b/encompass-cs/Collections/MessageStore.cs @@ -8,60 +8,60 @@ namespace Encompass { private readonly Dictionary _stores = new Dictionary(512); - private void RegisterMessageType() where TMessage : struct, IMessage + private void RegisterMessageType() where TMessage : struct { _stores.Add(typeof(TMessage), new TypedMessageStore()); } - private TypedMessageStore Lookup() where TMessage : struct, IMessage + private TypedMessageStore Lookup() where TMessage : struct { if (!_stores.ContainsKey(typeof(TMessage))) { RegisterMessageType(); } return _stores[typeof(TMessage)] as TypedMessageStore; } - public void AddMessage(in TMessage message) where TMessage : struct, IMessage + public void AddMessage(in TMessage message) where TMessage : struct { Lookup().Add(message); } - public void AddMessage(in TMessage message, double time) where TMessage : struct, IMessage + public void AddMessage(in TMessage message, double time) where TMessage : struct { Lookup().Add(message, time); } - public void AddMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct, IMessage + public void AddMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct { Lookup().AddIgnoringTimeDilation(message, time); } - public ref readonly TMessage First() where TMessage : struct, IMessage + public ref readonly TMessage First() where TMessage : struct { if (!Any()) { throw new NoMessageOfTypeException("No Message of type {0} exists", typeof(TMessage).Name); } return ref Lookup().First(); } - public ReadOnlySpan All() where TMessage : struct, IMessage + public ReadOnlySpan All() where TMessage : struct { return Lookup().All(); } - public bool Any() where TMessage : struct, IMessage + public bool Any() where TMessage : struct { return Lookup().Any(); } - public IEnumerable WithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + public IEnumerable WithEntity(int entityID) where TMessage : struct, IHasEntity { return Lookup().WithEntity(entityID); } - public ref readonly TMessage FirstWithEntity(int entityID) where TMessage : struct, IMessage + public ref readonly TMessage FirstWithEntity(int entityID) where TMessage : struct { return ref Lookup().FirstWithEntity(entityID); } - public bool SomeWithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + public bool SomeWithEntity(int entityID) where TMessage : struct, IHasEntity { return Lookup().SomeWithEntity(entityID); } diff --git a/encompass-cs/Collections/TypedComponentStore.cs b/encompass-cs/Collections/TypedComponentStore.cs index 5b837c6..fd7bb49 100644 --- a/encompass-cs/Collections/TypedComponentStore.cs +++ b/encompass-cs/Collections/TypedComponentStore.cs @@ -78,8 +78,8 @@ namespace Encompass { if (!_priorities.ContainsKey(entityID) || priority <= _priorities[entityID]) // if priorities are equal that means it's the same engine { - _priorities[entityID] = priority; ForceRemove(entityID); + _priorities[entityID] = priority; return true; } @@ -92,7 +92,6 @@ namespace Encompass { var storageIndex = _entityIDToStorageIndex[entityID]; _entityIDToStorageIndex.Remove(entityID); - _priorities.Remove(entityID); // move a component into the hole to maintain contiguous memory if (_nextID > 1 && storageIndex != _nextID - 1) diff --git a/encompass-cs/Collections/TypedMessageStore.cs b/encompass-cs/Collections/TypedMessageStore.cs index a9f222b..c99d8d5 100644 --- a/encompass-cs/Collections/TypedMessageStore.cs +++ b/encompass-cs/Collections/TypedMessageStore.cs @@ -9,7 +9,7 @@ namespace Encompass public abstract void Clear(); } - internal class TypedMessageStore : TypedMessageStore where TMessage : struct, IMessage + internal class TypedMessageStore : TypedMessageStore where TMessage : struct { // messages are placed in a contiguous region // so we can return the collection as a Span diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index da54e8e..3856af5 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -5,8 +5,6 @@ namespace Encompass { internal class ComponentManager { - private readonly DrawLayerManager _drawLayerManager; - private readonly ComponentStore _existingComponentStore; private readonly ComponentStore _immediateComponentStore; private readonly ComponentDeltaStore _replayStore; @@ -19,9 +17,8 @@ namespace Encompass internal ComponentBitSet ImmediateBits { get { return _immediateComponentStore.ComponentBitSet; } } internal ComponentBitSet ExistingBits { get { return _existingComponentStore.ComponentBitSet; } } - public ComponentManager(DrawLayerManager drawLayerManager, Dictionary typeToIndex) + public ComponentManager(Dictionary typeToIndex) { - this._drawLayerManager = drawLayerManager; _existingComponentStore = new ComponentStore(typeToIndex); _immediateComponentStore = new ComponentStore(typeToIndex); _replayStore = new ComponentDeltaStore(typeToIndex); @@ -47,11 +44,6 @@ namespace Encompass _upToDateComponentStore.SwapWith(componentStore); } - internal void RegisterDrawableComponent(int entityID, int layer) where TComponent : struct - { - _drawLayerManager.RegisterComponentWithLayer(entityID, layer); - } - internal void WriteComponents() { _existingComponentStore.UpdateUsing(_replayStore); @@ -264,7 +256,6 @@ namespace Encompass _immediateComponentStore.Remove(entityID); _replayStore.Remove(entityID); _upToDateComponentStore.Remove(entityID); - _drawLayerManager.UnRegisterEntityWithLayer(entityID); } _entitiesMarkedForRemoval.Clear(); @@ -276,7 +267,6 @@ namespace Encompass { _replayStore.Remove(entityID, priority); _upToDateComponentStore.Remove(entityID, priority); - _drawLayerManager.UnRegisterComponentWithLayer(entityID); return true; } return false; @@ -287,7 +277,6 @@ namespace Encompass if (_upToDateComponentStore.Remove(entityID, priority)) { _replayStore.Remove(entityID, priority); - _drawLayerManager.UnRegisterComponentWithLayer(entityID); } } diff --git a/encompass-cs/DrawLayerManager.cs b/encompass-cs/DrawLayerManager.cs deleted file mode 100644 index e500371..0000000 --- a/encompass-cs/DrawLayerManager.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Encompass.Exceptions; - -namespace Encompass -{ - internal class DrawLayerManager - { - private readonly SortedList _layerOrder = new SortedList(); - - private readonly Dictionary>> _layerIndexToTypeToID = new Dictionary>>(); - private readonly Dictionary> _layerIndexToGeneralRenderers = new Dictionary>(512); - - private readonly Dictionary> _typeToEntityToLayer = new Dictionary>(512); - public IEnumerable LayerOrder { get { return _layerOrder.Values; } } - - public DrawLayerManager() - { - RegisterDrawLayer(0); - } - - public void RegisterDrawLayer(int layer) - { - if (!_layerIndexToTypeToID.ContainsKey(layer)) - { - _layerOrder.Add(layer, layer); - _layerIndexToGeneralRenderers.Add(layer, new HashSet()); - _layerIndexToTypeToID.Add(layer, new Dictionary>()); - } - } - - public void RegisterOrderedDrawable() where TComponent : struct - { - if (!_typeToEntityToLayer.ContainsKey(typeof(TComponent))) - { - _typeToEntityToLayer.Add(typeof(TComponent), new Dictionary(128)); - } - - foreach (var pair in _layerIndexToTypeToID) - { - if (!pair.Value.ContainsKey(typeof(TComponent))) - { - pair.Value.Add(typeof(TComponent), new HashSet()); - } - } - } - - public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) - { - RegisterDrawLayer(layer); - var set = _layerIndexToGeneralRenderers[layer]; - set.Add(renderer); - } - - public void RegisterComponentWithLayer(int entityID, int layer) where TComponent : struct - { - if (!_layerIndexToTypeToID.ContainsKey(layer)) - { - throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer); - } - - if (_typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID)) - { - if (_typeToEntityToLayer[typeof(TComponent)][entityID] != layer) - { - UnRegisterComponentWithLayer(entityID); - - var set = _layerIndexToTypeToID[layer][typeof(TComponent)]; - set.Add(entityID); - - _typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer); - } - } - else - { - var set = _layerIndexToTypeToID[layer][typeof(TComponent)]; - set.Add(entityID); - - _typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer); - } - } - - public void UnRegisterComponentWithLayer(int entityID) where TComponent : struct - { - if (!_typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; } - - if (_typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID)) - { - var layer = _typeToEntityToLayer[typeof(TComponent)][entityID]; - _layerIndexToTypeToID[layer][typeof(TComponent)].Remove(entityID); - } - _typeToEntityToLayer[typeof(TComponent)].Remove(entityID); - } - - public void UnRegisterEntityWithLayer(int entityID) - { - foreach (var store in _layerIndexToTypeToID.Values) - { - foreach (var typeToSet in store) - { - var type = typeToSet.Key; - var set = typeToSet.Value; - - if (set.Contains(entityID)) - { - _typeToEntityToLayer[type].Remove(entityID); - set.Remove(entityID); - } - } - } - } - - public IEnumerable GeneralRenderersByLayer(int layer) - { - return _layerIndexToGeneralRenderers.ContainsKey(layer) ? - _layerIndexToGeneralRenderers[layer] : - Enumerable.Empty(); - } - - public IEnumerable<(int, Type)> AllInLayer(int layer) - { - foreach (var kvp in _layerIndexToTypeToID[layer]) - { - foreach (var id in kvp.Value) - { - yield return (id, kvp.Key); - } - } - } - } -} diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index b777a0e..cfdb76f 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -23,6 +23,7 @@ namespace Encompass internal readonly HashSet WriteImmediateTypes = new HashSet(); internal readonly HashSet QueryWithTypes = new HashSet(); internal readonly HashSet QueryWithoutTypes = new HashSet(); + internal readonly HashSet AddTypes = new HashSet(); internal readonly Dictionary WritePriorities = new Dictionary(); internal readonly int DefaultWritePriority = 0; @@ -58,6 +59,12 @@ namespace Encompass { _id = Guid.NewGuid(); + var addsAttribute = GetType().GetCustomAttribute(false); + if (addsAttribute != null) + { + AddTypes = addsAttribute.addTypes; + } + var sendsAttribute = GetType().GetCustomAttribute(false); if (sendsAttribute != null) { @@ -169,7 +176,7 @@ namespace Encompass _trackingManager = trackingManager; } - internal void CheckMessageRead() where TMessage : struct, IMessage + internal void CheckMessageRead() where TMessage : struct { if (!ReceiveTypes.Contains(typeof(TMessage))) { @@ -222,7 +229,7 @@ namespace Encompass /// /// Returns all Entities containing the specified Component type. /// - protected ReadOnlySpan ReadEntities() where TComponent : struct, IComponent + protected ReadOnlySpan ReadEntities() where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -247,7 +254,7 @@ namespace Encompass /// /// Returns an Entity containing the specified Component type. /// - protected ref readonly Entity ReadEntity() where TComponent : struct, IComponent + protected ref readonly Entity ReadEntity() where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -272,7 +279,7 @@ namespace Encompass /// /// Returns all of the Components with the specified Component Type. /// - protected ReadOnlySpan ReadComponents() where TComponent : struct, IComponent + protected ReadOnlySpan ReadComponents() where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -297,7 +304,7 @@ namespace Encompass /// /// Returns a Component with the specified Component Type. If multiples exist, an arbitrary Component is returned. /// - protected ref readonly TComponent ReadComponent() where TComponent : struct, IComponent + protected ref readonly TComponent ReadComponent() where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -322,7 +329,7 @@ namespace Encompass /// /// Returns true if any Component with the specified Component Type exists. /// - protected bool SomeComponent() where TComponent : struct, IComponent + protected bool SomeComponent() where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -344,7 +351,7 @@ namespace Encompass } } - private ref TComponent GetComponentHelper(int entityID) where TComponent : struct, IComponent + private ref TComponent GetComponentHelper(int entityID) where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -375,7 +382,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it reads the given Component Type. /// - protected ref readonly TComponent GetComponent(in Entity entity) where TComponent : struct, IComponent + protected ref readonly TComponent GetComponent(in Entity entity) where TComponent : struct { return ref GetComponentHelper(entity.ID); } @@ -386,7 +393,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that is Reads the given Component Type. /// - protected bool HasComponent(in Entity entity) where TComponent : struct, IComponent + protected bool HasComponent(in Entity entity) where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -444,7 +451,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Writes the given Component Type. /// - protected void SetComponent(in Entity entity, in TComponent component) where TComponent : struct, IComponent + protected void SetComponent(in Entity entity, in TComponent component) where TComponent : struct { var priority = WritePriorities.ContainsKey(typeof(TComponent)) ? WritePriorities[typeof(TComponent)] : DefaultWritePriority; @@ -471,11 +478,6 @@ namespace Encompass { _trackingManager.RegisterAddition(entity.ID, typeof(TComponent)); } - - if (written && component is IDrawableComponent drawableComponent) - { - _componentManager.RegisterDrawableComponent(entity.ID, drawableComponent.Layer); - } } /// @@ -484,8 +486,13 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Writes the given Component Type. /// - protected void AddComponent(in Entity entity, in TComponent component) where TComponent : struct, IComponent + protected void AddComponent(in Entity entity, in TComponent component) where TComponent : struct { + if (!AddTypes.Contains(typeof(TComponent))) + { + throw new IllegalWriteException("Engine {0} tried to add undeclared Component {1}", GetType().Name, typeof(TComponent).Name); + } + if (!EntityCreatedThisFrame(entity.ID)) { throw new IllegalWriteException("AddComponent used on Entity that was not created in this context. Use SetComponent instead."); @@ -502,11 +509,6 @@ namespace Encompass } _trackingManager.RegisterAddition(entity.ID, typeof(TComponent)); - - if (component is IDrawableComponent drawableComponent) - { - _componentManager.RegisterDrawableComponent(entity.ID, drawableComponent.Layer); - } } /// @@ -515,7 +517,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Sends the Message Type. /// - protected void SendMessage(in TMessage message) where TMessage : struct, IMessage + protected void SendMessage(in TMessage message) where TMessage : struct { if (!SendTypes.Contains(typeof(TMessage))) { @@ -529,7 +531,7 @@ namespace Encompass /// Sends a message after the specified number of seconds, respecting time dilation. /// /// The time in seconds that will elapse before the message is sent. - protected void SendMessage(in TMessage message, double time) where TMessage : struct, IMessage + protected void SendMessage(in TMessage message, double time) where TMessage : struct { _messageManager.AddMessage(message, time); } @@ -538,7 +540,7 @@ namespace Encompass /// Sends a message after the specified number of seconds, ignoring time dilation. /// /// The time in seconds that will elapse before the message is sent. - protected void SendMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct, IMessage + protected void SendMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct { _messageManager.AddMessageIgnoringTimeDilation(message, time); } @@ -549,7 +551,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Receives the specified Message Type. /// - protected ReadOnlySpan ReadMessages() where TMessage : struct, IMessage + protected ReadOnlySpan ReadMessages() where TMessage : struct { CheckMessageRead(); return _messageManager.GetMessagesByType(); @@ -561,7 +563,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Receives the specified Message Type. /// - protected ref readonly TMessage ReadMessage() where TMessage : struct, IMessage + protected ref readonly TMessage ReadMessage() where TMessage : struct { CheckMessageRead(); return ref _messageManager.First(); @@ -573,7 +575,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Receives the specified Message Type. /// - protected bool SomeMessage() where TMessage : struct, IMessage + protected bool SomeMessage() where TMessage : struct { CheckMessageRead(); return _messageManager.Any(); @@ -592,7 +594,7 @@ namespace Encompass /// Destroys an arbitrary Entity containing a Component of the specified Type. /// Entity destruction takes place after all the Engines have been processed by World Update. /// - protected void DestroyWith() where TComponent : struct, IComponent + protected void DestroyWith() where TComponent : struct { Destroy(ReadEntity()); } @@ -601,7 +603,7 @@ namespace Encompass /// Destroys all Entities containing a Component of the specified Type. /// Entity destruction takes place after all the Engines have been processed by World Update. /// - protected void DestroyAllWith() where TComponent : struct, IComponent + protected void DestroyAllWith() where TComponent : struct { foreach (var entity in ReadEntities()) { @@ -614,7 +616,7 @@ namespace Encompass /// Note that the Engine must Read the Component type that is being removed. /// If a Component with the specified type does not exist on the Entity, returns false and does not mutate the Entity. /// - protected void RemoveComponent(in Entity entity) where TComponent : struct, IComponent + protected void RemoveComponent(in Entity entity) where TComponent : struct { var priority = WritePriorities.ContainsKey(typeof(TComponent)) ? WritePriorities[typeof(TComponent)] : DefaultWritePriority; @@ -707,7 +709,7 @@ namespace Encompass /// The Message subtype. /// The entity that all messages in the IEnumerable refer to. /// - protected IEnumerable ReadMessagesWithEntity(in Entity entity) where TMessage : struct, IMessage, IHasEntity + protected IEnumerable ReadMessagesWithEntity(in Entity entity) where TMessage : struct, IHasEntity { CheckMessageRead(); return _messageManager.WithEntity(entity.ID); @@ -717,7 +719,7 @@ namespace Encompass /// Efficiently reads a single Message of a given type that references a given Entity. /// It is recommended to use this method in conjunction with SomeMessageWithEntity to prevent errors. /// - protected ref readonly TMessage ReadMessageWithEntity(in Entity entity) where TMessage : struct, IMessage, IHasEntity + protected ref readonly TMessage ReadMessageWithEntity(in Entity entity) where TMessage : struct, IHasEntity { CheckMessageRead(); return ref _messageManager.WithEntitySingular(entity.ID); @@ -726,7 +728,7 @@ namespace Encompass /// /// Efficiently checks if any Message of a given type referencing a given Entity exists. /// - protected bool SomeMessageWithEntity(in Entity entity) where TMessage : struct, IMessage, IHasEntity + protected bool SomeMessageWithEntity(in Entity entity) where TMessage : struct, IHasEntity { CheckMessageRead(); return _messageManager.SomeWithEntity(entity.ID); diff --git a/encompass-cs/Engines/Spawner.cs b/encompass-cs/Engines/Spawner.cs index 5b42469..348987e 100644 --- a/encompass-cs/Engines/Spawner.cs +++ b/encompass-cs/Engines/Spawner.cs @@ -6,7 +6,7 @@ namespace Encompass /// A Spawner is a special type of Engine that runs a Spawn method in response to each Message it receives. /// Spawners are useful for organizing the building of new Entities in your game. /// - public abstract class Spawner : Engine where TMessage : struct, IMessage + public abstract class Spawner : Engine where TMessage : struct { protected Spawner() : base() { diff --git a/encompass-cs/Exceptions/IllegalSendTypeException.cs b/encompass-cs/Exceptions/IllegalSendTypeException.cs deleted file mode 100644 index a374349..0000000 --- a/encompass-cs/Exceptions/IllegalSendTypeException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Encompass.Exceptions -{ - public class IllegalSendTypeException : Exception - { - public IllegalSendTypeException( - string format, - params object[] args - ) : base(string.Format(format, args)) { } - } -} diff --git a/encompass-cs/IMessage.cs b/encompass-cs/IMessage.cs deleted file mode 100644 index 6b76042..0000000 --- a/encompass-cs/IMessage.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Encompass -{ - /// - /// Structs that implement IMessage are considered to be Messages. - /// - public interface IMessage { } -} diff --git a/encompass-cs/Interfaces/IComponent.cs b/encompass-cs/Interfaces/IComponent.cs deleted file mode 100644 index d51b93c..0000000 --- a/encompass-cs/Interfaces/IComponent.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Encompass -{ - public interface IComponent { } -} diff --git a/encompass-cs/Interfaces/IDrawableComponent.cs b/encompass-cs/Interfaces/IDrawableComponent.cs deleted file mode 100644 index d150624..0000000 --- a/encompass-cs/Interfaces/IDrawableComponent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Encompass -{ - public interface IDrawableComponent - { - int Layer { get; } - } -} diff --git a/encompass-cs/MessageManager.cs b/encompass-cs/MessageManager.cs index 73f4c20..2abc907 100644 --- a/encompass-cs/MessageManager.cs +++ b/encompass-cs/MessageManager.cs @@ -13,17 +13,17 @@ namespace Encompass _timeManager = timeManager; } - internal void AddMessage(in TMessage message) where TMessage : struct, IMessage + internal void AddMessage(in TMessage message) where TMessage : struct { _messageStore.AddMessage(message); } - internal void AddMessage(in TMessage message, double time) where TMessage : struct, IMessage + internal void AddMessage(in TMessage message, double time) where TMessage : struct { _messageStore.AddMessage(message, time); } - internal void AddMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct, IMessage + internal void AddMessageIgnoringTimeDilation(in TMessage message, double time) where TMessage : struct { _messageStore.AddMessageIgnoringTimeDilation(message, time); } @@ -38,32 +38,32 @@ namespace Encompass _messageStore.ProcessDelayedMessages(dt * _timeManager.TimeDilationFactor, dt); } - internal ReadOnlySpan GetMessagesByType() where TMessage : struct, IMessage + internal ReadOnlySpan GetMessagesByType() where TMessage : struct { return _messageStore.All(); } - internal bool Any() where TMessage : struct, IMessage + internal bool Any() where TMessage : struct { return _messageStore.Any(); } - internal ref readonly TMessage First() where TMessage : struct, IMessage + internal ref readonly TMessage First() where TMessage : struct { return ref _messageStore.First(); } - internal IEnumerable WithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + internal IEnumerable WithEntity(int entityID) where TMessage : struct, IHasEntity { return _messageStore.WithEntity(entityID); } - internal ref readonly TMessage WithEntitySingular(int entityID) where TMessage : struct, IMessage, IHasEntity + internal ref readonly TMessage WithEntitySingular(int entityID) where TMessage : struct, IHasEntity { return ref _messageStore.FirstWithEntity(entityID); } - internal bool SomeWithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + internal bool SomeWithEntity(int entityID) where TMessage : struct, IHasEntity { return _messageStore.SomeWithEntity(entityID); } diff --git a/encompass-cs/RenderManager.cs b/encompass-cs/RenderManager.cs index f2031ae..fcf376a 100644 --- a/encompass-cs/RenderManager.cs +++ b/encompass-cs/RenderManager.cs @@ -1,51 +1,27 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace Encompass { internal class RenderManager { private readonly EntityManager _entityManager; - private readonly DrawLayerManager _drawLayerManager; + private readonly List renderers = new List(); - private readonly Dictionary> _drawComponentTypeToOrderedRenderer = new Dictionary>(256); - - public RenderManager(EntityManager entityManager, DrawLayerManager drawLayerManager) + public RenderManager(EntityManager entityManager) { _entityManager = entityManager; - _drawLayerManager = drawLayerManager; } - public void RegisterOrderedRenderer(Action renderAction) where TComponent : struct + public void AddRenderer(Renderer renderer) { - _drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction); - _drawLayerManager.RegisterOrderedDrawable(); - } - - public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) - { - _drawLayerManager.RegisterGeneralRendererWithLayer(renderer, layer); + renderers.Add(renderer); } public void Draw() { - foreach (var layer in _drawLayerManager.LayerOrder) + foreach (var renderer in renderers) { - var generalRendererSet = _drawLayerManager.GeneralRenderersByLayer(layer); - - foreach (var (entityID, componentType) in _drawLayerManager.AllInLayer(layer)) - { - if (_drawComponentTypeToOrderedRenderer.ContainsKey(componentType)) - { - var internalRenderAction = _drawComponentTypeToOrderedRenderer[componentType]; - internalRenderAction(_entityManager.GetEntity(entityID)); - } - } - - foreach (var generalRenderer in generalRendererSet) - { - generalRenderer.Render(); - } + renderer.Render(); } } } diff --git a/encompass-cs/Renderer.cs b/encompass-cs/Renderer.cs index 7891489..e13d654 100644 --- a/encompass-cs/Renderer.cs +++ b/encompass-cs/Renderer.cs @@ -18,47 +18,49 @@ namespace Encompass _componentManager = componentManager; } - protected ReadOnlySpan ReadEntities() where TComponent : struct, IComponent + public abstract void Render(); + + protected ReadOnlySpan ReadEntities() where TComponent : struct { return _componentManager.GetExistingEntities(); } - protected IEnumerable ReadEntitiesAsEnumerable() where TComponent : struct, IComponent + protected IEnumerable ReadEntitiesAsEnumerable() where TComponent : struct { return _componentManager.GetExistingEntitiesAsEnumerable(); } - protected ref readonly Entity ReadEntity() where TComponent : struct, IComponent + protected ref readonly Entity ReadEntity() where TComponent : struct { return ref _componentManager.ExistingSingularEntity(); } - protected ReadOnlySpan ReadComponents() where TComponent : struct, IComponent + protected ReadOnlySpan ReadComponents() where TComponent : struct { return _componentManager.GetComponentsByType(); } - protected IEnumerable ReadComponentsAsEnumerable() where TComponent : struct, IComponent + protected IEnumerable ReadComponentsAsEnumerable() where TComponent : struct { return _componentManager.GetComponentsByTypeEnumerable(); } - protected ref readonly TComponent ReadComponent() where TComponent : struct, IComponent + protected ref readonly TComponent ReadComponent() where TComponent : struct { return ref _componentManager.ExistingSingular(); } - protected ref readonly TComponent GetComponent(Entity entity) where TComponent : struct, IComponent + protected ref readonly TComponent GetComponent(Entity entity) where TComponent : struct { return ref _componentManager.GetComponentByEntityAndType(entity.ID); } - protected bool HasComponent(Entity entity) where TComponent : struct, IComponent + protected bool HasComponent(Entity entity) where TComponent : struct { return _componentManager.EntityHasComponentOfType(entity.ID); } - protected bool SomeComponent() where TComponent : struct, IComponent + protected bool SomeComponent() where TComponent : struct { return _componentManager.SomeExistingComponent(); } diff --git a/encompass-cs/Renderers/GeneralRenderer.cs b/encompass-cs/Renderers/GeneralRenderer.cs deleted file mode 100644 index ffface9..0000000 --- a/encompass-cs/Renderers/GeneralRenderer.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Encompass -{ - /// - /// GeneralRenderer is a Renderer which generically reads the game state in order to draw elements to the screen. - /// GeneralRenderers have a layer specified when they are added to the World. - /// - public abstract class GeneralRenderer : Renderer - { - public abstract void Render(); - } -} diff --git a/encompass-cs/Renderers/OrderedRenderer.cs b/encompass-cs/Renderers/OrderedRenderer.cs deleted file mode 100644 index 5b462b3..0000000 --- a/encompass-cs/Renderers/OrderedRenderer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Encompass -{ - /// - /// OrdereredRenderer provides a structure for the common pattern of wishing to draw a specific DrawComponent at a specific layer. - /// - public abstract class OrderedRenderer : Renderer where TComponent : struct, IComponent, IDrawableComponent - { - public abstract void Render(Entity entity, in TComponent drawComponent); - - internal void InternalRender(Entity entity) - { - ref readonly var component = ref GetComponent(entity); - Render(entity, component); - } - } -} diff --git a/encompass-cs/UberEngine.cs b/encompass-cs/UberEngine.cs index 604b337..7a745e3 100644 --- a/encompass-cs/UberEngine.cs +++ b/encompass-cs/UberEngine.cs @@ -14,6 +14,7 @@ namespace Encompass { _componentTypes = componentTypes; _messageTypes = messageTypes; + AddTypes.UnionWith(componentTypes); ReadTypes.UnionWith(componentTypes); WriteTypes.UnionWith(componentTypes); SendTypes.UnionWith(messageTypes); @@ -54,7 +55,7 @@ namespace Encompass // we can't reflect invoke on byref returns or Span returns right now... so we have non-return wrapper methods - protected void CallAllComponentMethods() where TComponent : struct, IComponent + protected void CallAllComponentMethods() where TComponent : struct { ReadComponent(); ReadComponents(); @@ -69,7 +70,7 @@ namespace Encompass AddComponent(Entity, default); } - protected void CallAllMessageMethods() where TMessage : struct, IMessage + protected void CallAllMessageMethods() where TMessage : struct { SendMessageIgnoringTimeDilation(default, 0.1); SendMessage(default); @@ -79,7 +80,7 @@ namespace Encompass SomeMessage(); } - protected void CallAllEntityMessageMethods() where TMessage : struct, IMessage, IHasEntity + protected void CallAllEntityMessageMethods() where TMessage : struct, IHasEntity { ReadMessagesWithEntity(Entity); ReadMessageWithEntity(Entity); diff --git a/encompass-cs/UberRenderer.cs b/encompass-cs/UberRenderer.cs index a3ab60b..63b999c 100644 --- a/encompass-cs/UberRenderer.cs +++ b/encompass-cs/UberRenderer.cs @@ -20,7 +20,7 @@ namespace Encompass } // can't reflect invoke on Span returns... - public void Render() + public override void Render() { foreach (var type in _componentTypes) { @@ -28,7 +28,7 @@ namespace Encompass } } - protected void CallAllComponentMethods() where TComponent : struct, IComponent + protected void CallAllComponentMethods() where TComponent : struct { ReadEntity(); ReadEntities(); diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index efaf698..1a6055c 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -26,7 +26,6 @@ namespace Encompass private readonly EntityManager _entityManager; private readonly MessageManager _messageManager; private readonly TimeManager _timeManager; - private readonly DrawLayerManager _drawLayerManager; private readonly RenderManager _renderManager; private readonly TrackingManager _trackingManager; @@ -36,18 +35,15 @@ namespace Encompass private readonly HashSet _messageTypes = new HashSet(); private readonly Dictionary _typeToIndex = new Dictionary(); - private bool _rendererRegistered = false; - public WorldBuilder(int entityCapacity = 32768) { _entityCapacity = entityCapacity; - _drawLayerManager = new DrawLayerManager(); _timeManager = new TimeManager(); _trackingManager = new TrackingManager(); - _componentManager = new ComponentManager(_drawLayerManager, _typeToIndex); + _componentManager = new ComponentManager(_typeToIndex); _messageManager = new MessageManager(_timeManager); _entityManager = new EntityManager(_componentManager, entityCapacity); - _renderManager = new RenderManager(_entityManager, _drawLayerManager); + _renderManager = new RenderManager(_entityManager); _startingExistingComponentStore = new ComponentStore(_typeToIndex); _startingUpToDateComponentStore = new ComponentStore(_typeToIndex); @@ -64,7 +60,7 @@ namespace Encompass /// /// Specifies that the given Message should be sent immediately on the first World Update. /// - public void SendMessage(in TMessage message) where TMessage : struct, IMessage + public void SendMessage(in TMessage message) where TMessage : struct { _messageManager.AddMessage(message); } @@ -72,7 +68,7 @@ namespace Encompass /// /// Specifies that the given Message should be sent after the specified number of seconds after the first World Update. /// - public void SendMessage(in TMessage message, double time) where TMessage : struct, IMessage + public void SendMessage(in TMessage message, double time) where TMessage : struct { _messageManager.AddMessage(message, time); } @@ -80,20 +76,21 @@ namespace Encompass /// /// Sets Component data for the specified Component Type on the specified Entity. /// - public void SetComponent(Entity entity, in TComponent component) where TComponent : struct, IComponent + public void SetComponent(Entity entity, in TComponent component) where TComponent : struct { RegisterComponentType(); _startingExistingComponentStore.Set(entity.ID, component); _startingUpToDateComponentStore.Set(entity.ID, component); - - if (component is IDrawableComponent drawableComponent) - { - _componentManager.RegisterDrawableComponent(entity.ID, drawableComponent.Layer); - _drawLayerManager.RegisterOrderedDrawable(); - } } - internal void RegisterComponentType() where TComponent : struct, IComponent + internal void RegisterComponentTypeNonGeneric(Type type) + { + var method = GetType().GetMethod("RegisterComponentType", BindingFlags.NonPublic | BindingFlags.Instance); + var generic = method.MakeGenericMethod(type); + generic.Invoke(this, null); + } + + internal void RegisterComponentType() where TComponent : struct { if (!_typeToIndex.ContainsKey(typeof(TComponent))) { @@ -158,6 +155,26 @@ namespace Encompass _senders.Add(engine); } + foreach (var componentType in engine.ReadTypes) + { + RegisterComponentTypeNonGeneric(componentType); + } + + foreach (var componentType in engine.AddTypes) + { + RegisterComponentTypeNonGeneric(componentType); + } + + foreach (var componentType in engine.WriteTypes) + { + RegisterComponentTypeNonGeneric(componentType); + } + + foreach (var componentType in engine.WriteImmediateTypes) + { + RegisterComponentTypeNonGeneric(componentType); + } + foreach (var componentType in engine.QueryWithTypes) { _trackingManager.RegisterComponentTypeToEngine(componentType, engine); @@ -200,44 +217,13 @@ namespace Encompass } /// - /// Registers a draw layer. This must be done before any Renderers are registered. + /// Adds the specified Renderer to the World. /// - /// The draw layer to register. - public void RegisterDrawLayer(int layer) + public void AddRenderer(Renderer renderer) { - if (_rendererRegistered) - { - throw new IllegalDrawLayerException("Cannot register a draw layer after a Renderer has been registered."); - } - _drawLayerManager.RegisterDrawLayer(layer); - } - - /// - /// Adds the specified OrderedRenderer to the World. - /// - public OrderedRenderer AddOrderedRenderer(OrderedRenderer renderer) where TComponent : struct, IComponent, IDrawableComponent - { - RegisterComponentType(); - renderer.AssignEntityManager(_entityManager); renderer.AssignComponentManager(_componentManager); - _renderManager.RegisterOrderedRenderer(renderer.InternalRender); - _rendererRegistered = true; - return renderer; - } - - /// - /// Adds the specified GeneralRenderer to the World at the specified layer. - /// Higher layer numbers draw on top of lower layer numbers. - /// - /// An instance of a GeneralRenderer. - /// The layer at which the GeneralRenderer should render. Higher numbers draw over lower numbers. - public TRenderer AddGeneralRenderer(TRenderer renderer, int layer) where TRenderer : GeneralRenderer - { renderer.AssignEntityManager(_entityManager); - renderer.AssignComponentManager(_componentManager); - _renderManager.RegisterGeneralRendererWithLayer(renderer, layer); - _rendererRegistered = true; - return renderer; + _renderManager.AddRenderer(renderer); } private void BuildEngineGraph() @@ -441,44 +427,20 @@ namespace Encompass { var dummyTimeManager = new TimeManager(); var dummyMessageManager = new MessageManager(dummyTimeManager); - var dummyDrawLayerManager = new DrawLayerManager(); var dummyTrackingManager = new TrackingManager(); - var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, _typeToIndex); + var dummyComponentManager = new ComponentManager(_typeToIndex); var dummyEntityManager = new EntityManager(dummyComponentManager, _entityCapacity); - var dummyRenderManager = new RenderManager(dummyEntityManager, dummyDrawLayerManager); - - // doing reflection to grab all component types, because not all writes need to be declared - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - foreach (var componentType in assembly.GetTypes()) - { - if (typeof(IComponent).IsAssignableFrom(componentType) && componentType.IsValueType && !componentType.IsEnum && !componentType.IsPrimitive) - { - var method = typeof(WorldBuilder).GetMethod("RegisterComponentType", BindingFlags.NonPublic | BindingFlags.Instance); - var generic = method.MakeGenericMethod(componentType); - generic.Invoke(this, null); - - var dummyRegisterMethod = typeof(ComponentManager).GetMethod("RegisterComponentType", BindingFlags.Public | BindingFlags.Instance); - var dummyGeneric = dummyRegisterMethod.MakeGenericMethod(componentType); - dummyGeneric.Invoke(dummyComponentManager, null); - } - - if (componentType.GetInterface("IDrawableComponent") != null) - { - // register draw layer using property value - var instance = Activator.CreateInstance(componentType); - var layerPropertyInfo = componentType.GetProperty("Layer"); - dummyDrawLayerManager.RegisterDrawLayer((int)layerPropertyInfo.GetValue(instance)); - - var drawLayerManagerRegisterMethod = typeof(DrawLayerManager).GetMethod("RegisterOrderedDrawable"); - var drawLayerManagerRegisterGenericMethod = drawLayerManagerRegisterMethod.MakeGenericMethod(componentType); - drawLayerManagerRegisterGenericMethod.Invoke(dummyDrawLayerManager, null); - } - } - } + var dummyRenderManager = new RenderManager(dummyEntityManager); var prepEngineOrder = new List(); + foreach (var componentType in _componentTypesToPreload) + { + var dummyRegisterMethod = typeof(ComponentManager).GetMethod("RegisterComponentType", BindingFlags.Public | BindingFlags.Instance); + var dummyGeneric = dummyRegisterMethod.MakeGenericMethod(componentType); + dummyGeneric.Invoke(dummyComponentManager, null); + } + var uberEngine = new UberEngine(_componentTypesToPreload, messageTypes); uberEngine.AssignEntityManager(dummyEntityManager); diff --git a/test/ComponentTest.cs b/test/ComponentTest.cs index 9c6e2e7..d6ab590 100644 --- a/test/ComponentTest.cs +++ b/test/ComponentTest.cs @@ -8,12 +8,12 @@ namespace Tests { public class ComponentTests { - struct MockComponent : IComponent + struct MockComponent { public int myInt; } - struct EntityMessage : IMessage + struct EntityMessage { public Entity entity; } @@ -33,7 +33,7 @@ namespace Tests } } - struct AddComponentTestMessage : IMessage + struct AddComponentTestMessage { public Entity entity; public MockComponent mockComponent; @@ -62,8 +62,6 @@ namespace Tests var entity = worldBuilder.CreateEntity(); - const string MyString = "hello"; - MockComponent mockComponent; mockComponent.myInt = 3; @@ -174,7 +172,7 @@ namespace Tests Assert.DoesNotThrow(() => world.Update(0.01)); } - struct AddMockComponentMessage : IMessage + struct AddMockComponentMessage { public Entity entity; public MockComponent mockComponent; @@ -271,7 +269,7 @@ namespace Tests Assert.AreEqual(mockComponent, gottenMockComponent); } - struct HasComponentTestMessage : IMessage + struct HasComponentTestMessage { public Entity entity; } @@ -369,7 +367,7 @@ namespace Tests Assert.IsFalse(hasComponentRuntimeTypeResult); } - struct RemoveComponentTestMessage : IMessage + struct RemoveComponentTestMessage { public Entity entity; } @@ -463,7 +461,7 @@ namespace Tests hasComponentResult.Should().BeFalse(); } - struct CheckHasMockComponentMessage : IMessage + struct CheckHasMockComponentMessage { public Entity entity; public bool shouldHaveComponent; diff --git a/test/EngineTest.cs b/test/EngineTest.cs index c9a131d..3a4ff00 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -10,7 +10,7 @@ using Encompass.Exceptions; namespace Tests { - struct MockComponent : IComponent + struct MockComponent { public int myInt; } @@ -271,7 +271,7 @@ namespace Tests Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to update undeclared Component MockComponent")); } - struct MockMessage : IMessage + struct MockMessage { public string myString; } @@ -435,7 +435,7 @@ namespace Tests Assert.Throws(() => world.Update(0.01f)); } - struct EntityMessage : IMessage, IHasEntity + struct EntityMessage : IHasEntity { public EntityMessage(Entity entity, int myInt) { @@ -650,7 +650,7 @@ namespace Tests world.Update(0.01f); } - struct DestroyerComponent : IComponent { } + struct DestroyerComponent { } [Reads(typeof(DestroyerComponent))] class DestroyerEngine : Engine @@ -955,7 +955,7 @@ namespace Tests resultComponents.Should().BeEmpty(); } - struct DestroyComponentMessage : IMessage { public Entity entity; } + struct DestroyComponentMessage { public Entity entity; } [Reads(typeof(MockComponent))] [Writes(typeof(MockComponent))] @@ -1007,7 +1007,7 @@ namespace Tests Assert.Throws(() => world.Update(0.01), "No component of type MockComponent exists"); } - struct MockComponentB : IComponent + struct MockComponentB { private int value; @@ -1324,6 +1324,7 @@ namespace Tests undilatedDeltaTime.Should().Be(0.5); } + [Adds(typeof(MockComponent))] class AddComponentWithoutPriorityEngine : Engine { public override void Update(double dt) @@ -1380,6 +1381,7 @@ namespace Tests Assert.Throws(() => world.Update(0.01)); } + [Adds(typeof(MockComponentB))] [WritesImmediate(typeof(MockComponentB))] class AddImmediateComponentEngine : Engine { @@ -1450,9 +1452,9 @@ namespace Tests public class QueryTests { - struct MockComponentB : IComponent { } - struct MockComponentC : IComponent { } - struct MockComponentD : IComponent { } + struct MockComponentB { } + struct MockComponentC { } + struct MockComponentD { } [Writes(typeof(MockComponentB))] [QueryWith(typeof(MockComponent), typeof(MockComponentB))] @@ -1902,7 +1904,7 @@ namespace Tests _components.Should().NotBeEmpty(); } - struct MockTimerComponent : IComponent + struct MockTimerComponent { public double Timer { get; } diff --git a/test/OrderedRendererTest.cs b/test/OrderedRendererTest.cs deleted file mode 100644 index 92cb3b8..0000000 --- a/test/OrderedRendererTest.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; - -using NUnit.Framework; -using FluentAssertions; -using Encompass; -using System.Collections.Generic; - -namespace Tests -{ - public class OrderedRendererTest - { - struct AComponent : IComponent { } - struct BComponent : IComponent { } - struct CComponent : IComponent { } - - struct TestDrawComponent : IComponent, IDrawableComponent - { - public int Layer { get; set; } - } - - class TestRenderer : OrderedRenderer - { - public override void Render(Entity entity, in TestDrawComponent testDrawComponent) { } - } - - static bool called = false; - class DeactivatedRenderer : TestRenderer - { - public override void Render(Entity entity, in TestDrawComponent testDrawComponent) - { - called = true; - } - } - - static bool calledOnDraw = false; - static (TestDrawComponent, Entity) resultComponent; - - class CalledRenderer : OrderedRenderer - { - public override void Render(Entity entity, in TestDrawComponent testDrawComponent) - { - resultComponent = (testDrawComponent, entity); - calledOnDraw = true; - } - } - - [Test] - public void RenderMethodCalledOnWorldDraw() - { - var worldBuilder = new WorldBuilder(); - worldBuilder.RegisterDrawLayer(2); - - var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer()); - - AComponent aComponent; - CComponent cComponent; - - var testDrawComponent = new TestDrawComponent { Layer = 2 }; - - var entity = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entity, aComponent); - worldBuilder.SetComponent(entity, cComponent); - worldBuilder.SetComponent(entity, testDrawComponent); - - var world = worldBuilder.Build(); - - world.Update(0.01f); - world.Draw(); - - Assert.IsTrue(calledOnDraw); - resultComponent.Should().BeEquivalentTo((testDrawComponent, entity)); - } - - [Reads(typeof(TestDrawComponent))] - class DestroyerEngine : Engine - { - public override void Update(double dt) - { - foreach (var entity in ReadEntities()) - { - Destroy(entity); - } - } - } - [Test] - public void RenderMethodNotCalledAfterDestroy() - { - calledOnDraw = false; - - var worldBuilder = new WorldBuilder(); - worldBuilder.RegisterDrawLayer(1); - - worldBuilder.AddEngine(new DestroyerEngine()); - var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer()); - - TestDrawComponent testDrawComponent = new TestDrawComponent { Layer = 1 }; - - var entity = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entity, testDrawComponent); - - var world = worldBuilder.Build(); - - world.Update(0.01); - world.Draw(); - - Assert.IsFalse(calledOnDraw); - } - } -} diff --git a/test/GeneralRendererTest.cs b/test/RendererTest.cs similarity index 88% rename from test/GeneralRendererTest.cs rename to test/RendererTest.cs index 32659c0..53dbbc3 100644 --- a/test/GeneralRendererTest.cs +++ b/test/RendererTest.cs @@ -5,13 +5,13 @@ namespace Tests { public static class GeneralRendererTest { - struct AComponent : IComponent { } + struct AComponent { } public class SingletonRead { static (AComponent, Entity) result; - class TestRenderer : GeneralRenderer + class TestRenderer : Renderer { public override void Render() { @@ -24,7 +24,7 @@ namespace Tests public void SingletonComponent() { var worldBuilder = new WorldBuilder(); - worldBuilder.AddGeneralRenderer(new TestRenderer(), 1); + worldBuilder.AddRenderer(new TestRenderer()); AComponent aComponent; @@ -46,7 +46,7 @@ namespace Tests public void MultipleComponents() { var worldBuilder = new WorldBuilder(); - worldBuilder.AddGeneralRenderer(new TestRenderer(), 1); + worldBuilder.AddRenderer(new TestRenderer()); AComponent aComponent; AComponent aComponentTwo; diff --git a/test/SpawnerTest.cs b/test/SpawnerTest.cs index 1c7c822..b5a65b0 100644 --- a/test/SpawnerTest.cs +++ b/test/SpawnerTest.cs @@ -5,8 +5,8 @@ namespace Tests { public class SpawnerTest { - struct TestComponent : IComponent { } - struct SpawnMessageA : IMessage { } + struct TestComponent { } + struct SpawnMessageA { } static Entity resultEntity; diff --git a/test/WorldBuilderTest.cs b/test/WorldBuilderTest.cs index 530e120..b9b4947 100644 --- a/test/WorldBuilderTest.cs +++ b/test/WorldBuilderTest.cs @@ -13,8 +13,8 @@ namespace Tests { public class EngineCycleSimple { - struct AMessage : IMessage { } - struct BMessage : IMessage { } + struct AMessage { } + struct BMessage { } [Receives(typeof(AMessage))] [Sends(typeof(BMessage))] @@ -51,10 +51,10 @@ namespace Tests public class EngineCycleComplex { - struct AMessage : IMessage { } - struct BMessage : IMessage { } - struct CMessage : IMessage { } - struct DMessage : IMessage { } + struct AMessage { } + struct BMessage { } + struct CMessage { } + struct DMessage { } [Receives(typeof(AMessage))] [Sends(typeof(BMessage))] @@ -142,12 +142,12 @@ namespace Tests public class MultipleEngineWriteWithPriority { - struct SetMessage : IMessage + struct SetMessage { public Entity entity; } - struct AComponent : IComponent + struct AComponent { public int myInt; } @@ -211,12 +211,12 @@ namespace Tests public class DefaultWritePriority { - struct SetMessage : IMessage + struct SetMessage { public Entity entity; } - struct AComponent : IComponent + struct AComponent { public int myInt; } @@ -298,7 +298,7 @@ namespace Tests public class EngineMessageSelfCycle { - struct AMessage : IMessage { } + struct AMessage { } [Receives(typeof(AMessage))] [Sends(typeof(AMessage))] @@ -319,28 +319,6 @@ namespace Tests } } - public class IllegalWriteType - { - struct ANonMessage { } - - [Sends(typeof(ANonMessage))] - class MyEngine : Engine - { - public override void Update(double dt) - { - - } - } - - [Test] - public void ThrowsError() - { - var worldBuilder = new WorldBuilder(); - - Assert.Throws(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component"); - } - } - public class PriorityConflict { [Writes(typeof(MockComponent), 2)] @@ -407,13 +385,13 @@ namespace Tests { static List order = new List(); - struct AComponent : IComponent { } - struct BComponent : IComponent { } + struct AComponent { } + struct BComponent { } - struct AMessage : IMessage { } - struct BMessage : IMessage { } - struct CMessage : IMessage { } - struct DMessage : IMessage { } + struct AMessage { } + struct BMessage { } + struct CMessage { } + struct DMessage { } [Sends(typeof(AMessage))] class AEngine : Engine @@ -520,8 +498,8 @@ namespace Tests { static List order = new List(); - struct AMessage : IMessage { } - struct BMessage : IMessage { } + struct AMessage { } + struct BMessage { } [Sends(typeof(AMessage), typeof(BMessage))] class AEngine : Engine @@ -558,57 +536,5 @@ namespace Tests Assert.That(order.IndexOf(engineA), Is.LessThan(order.IndexOf(engineB))); } } - - public class DrawLayerRegister - { - struct AComponent : IComponent, IDrawableComponent - { - public int Layer { get; } - } - - struct BComponent : IComponent, IDrawableComponent - { - public int Layer { get => 3; } - } - - class ARenderer : OrderedRenderer - { - public override void Render(Entity entity, in AComponent drawComponent) { } - } - - class BRenderer : OrderedRenderer - { - public override void Render(Entity entity, in BComponent drawComponent) { } - } - - [Test] - public void DrawLayerRegisterAfterOrderedRendererRegisterThrows() - { - var worldBuilder = new WorldBuilder(); - - var rendererA = worldBuilder.AddOrderedRenderer(new ARenderer()); - - Assert.Throws(() => worldBuilder.RegisterDrawLayer(1)); - } - - [Test] - public void DrawLayerRegisterBeforeOrderedRendererDoesNotThrow() - { - var worldBuilder = new WorldBuilder(); - - Assert.DoesNotThrow(() => worldBuilder.RegisterDrawLayer(1)); - Assert.DoesNotThrow(() => worldBuilder.AddOrderedRenderer(new ARenderer())); - } - - [Test] - public void DrawLayerWithProperty() - { - var worldBuilder = new WorldBuilder(); - - var rendererB = worldBuilder.AddOrderedRenderer(new BRenderer()); - - Assert.DoesNotThrow(() => worldBuilder.Build()); - } - } } } diff --git a/test/WorldTest.cs b/test/WorldTest.cs deleted file mode 100644 index 6ce089b..0000000 --- a/test/WorldTest.cs +++ /dev/null @@ -1,81 +0,0 @@ -using NUnit.Framework; -using FluentAssertions; - -using System; -using System.Collections.Generic; -using System.Text; - -using Encompass; - -namespace Tests -{ - public class WorldTest - { - struct TestComponent : IComponent { } - struct TestDrawComponent : IComponent, IDrawableComponent - { - public int Layer { get; set; } - } - - static List drawOrder = new List(); - - class TestEntityRenderer : OrderedRenderer - { - public override void Render(Entity entity, in TestDrawComponent testDrawComponent) - { - drawOrder.Add(entity); - } - } - - class TestGeneralRenderer : GeneralRenderer - { - public override void Render() - { - drawOrder.Add(this); - } - } - - [Test] - public void DrawOrder() - { - var worldBuilder = new WorldBuilder(); - worldBuilder.RegisterDrawLayer(1); - worldBuilder.RegisterDrawLayer(2); - worldBuilder.RegisterDrawLayer(3); - worldBuilder.RegisterDrawLayer(4); - worldBuilder.RegisterDrawLayer(7); - - worldBuilder.AddOrderedRenderer(new TestEntityRenderer()); - var testGeneralRenderer = worldBuilder.AddGeneralRenderer(new TestGeneralRenderer(), 7); - - TestComponent testComponent; - TestDrawComponent drawComponentThree = new TestDrawComponent { Layer = 3 }; - var drawComponentTwo = new TestDrawComponent { Layer = 2 }; - var drawComponentOne = new TestDrawComponent { Layer = 1 }; - var drawComponentFour = new TestDrawComponent { Layer = 4 }; - - var entity = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entity, testComponent); - worldBuilder.SetComponent(entity, drawComponentThree); - - var entityTwo = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entityTwo, testComponent); - worldBuilder.SetComponent(entityTwo, drawComponentTwo); - - var entityThree = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entityThree, testComponent); - worldBuilder.SetComponent(entityThree, drawComponentThree); - - var entityFour = worldBuilder.CreateEntity(); - worldBuilder.SetComponent(entityFour, testComponent); - worldBuilder.SetComponent(entityFour, drawComponentFour); - - var world = worldBuilder.Build(); - - world.Update(0.01f); - world.Draw(); - - drawOrder.Should().BeEquivalentTo(entityFour, entityTwo, entity, entityThree, testGeneralRenderer); - } - } -}