diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index ea5e2fc..9bf4550 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -18,10 +18,6 @@ namespace Encompass private readonly List activeComponents = new List(); private readonly List inactiveComponents = new List(); - private readonly HashSet componentsToActivate = new HashSet(); - private readonly HashSet componentsToDeactivate = new HashSet(); - private readonly HashSet componentsToRemove = new HashSet(); - //shared references with EntityManager private readonly HashSet entitiesWithAddedComponents; private readonly HashSet entitiesWithRemovedComponents; @@ -60,7 +56,7 @@ namespace Encompass componentIDToEntityID[componentID] = entityID; inactiveComponents.Add(componentID); - MarkForActivation(componentID); + Activate(componentID); entitiesWithAddedComponents.Add(entityID); @@ -158,91 +154,58 @@ namespace Encompass { var componentIDs = entityIDToComponentIDs[entityID]; - foreach (var componentID in componentIDs) + for (int i = componentIDs.Count - 1; i >= 0; i--) { - MarkForRemoval(componentID); + Remove(componentIDs[i]); } } - internal void MarkForActivation(Guid componentID) + internal void Activate(Guid componentID) { - componentsToActivate.Add(componentID); + if (inactiveComponents.Remove(componentID)) + { + activeComponents.Add(componentID); + } var entityID = GetEntityIDByComponentID(componentID); entitiesWithAddedComponents.Add(entityID); } - internal void MarkForDeactivation(Guid componentID) + internal void Deactivate(Guid componentID) { - componentsToDeactivate.Add(componentID); + if (activeComponents.Remove(componentID)) + { + inactiveComponents.Add(componentID); + } var entityID = GetEntityIDByComponentID(componentID); entitiesWithRemovedComponents.Add(entityID); } - internal void MarkForRemoval(Guid componentID) + internal void Remove(Guid componentID) { - componentsToRemove.Add(componentID); + var component = IDToComponent[componentID]; + var type = componentIDToType[componentID]; + + activeComponents.Remove(componentID); + inactiveComponents.Remove(componentID); + + var entityID = componentIDToEntityID[componentID]; + if (entityIDToComponentIDs.ContainsKey(entityID)) + { + entityIDToComponentIDs[entityID].Remove(componentID); + } + + IDToComponent.Remove(componentID); + componentIDToType.Remove(componentID); + componentIDToEntityID.Remove(componentID); + typeToComponentIDs[type].Remove(componentID); + + drawLayerManager.UnRegisterComponentWithLayer(componentID); - var entityID = GetEntityIDByComponentID(componentID); entitiesWithRemovedComponents.Add(entityID); } - internal void ActivateMarkedComponents() - { - foreach (var componentID in componentsToActivate) - { - var component = IDToComponent[componentID]; - if (inactiveComponents.Remove(componentID)) - { - activeComponents.Add(componentID); - } - } - - componentsToActivate.Clear(); - } - - internal void DeactivateMarkedComponents() - { - foreach (var componentID in componentsToDeactivate) - { - var component = IDToComponent[componentID]; - if (activeComponents.Remove(componentID)) - { - inactiveComponents.Add(componentID); - } - } - - componentsToDeactivate.Clear(); - } - - public void RemoveMarkedComponents() - { - foreach (var componentID in componentsToRemove) - { - var component = IDToComponent[componentID]; - var type = componentIDToType[componentID]; - - activeComponents.Remove(componentID); - inactiveComponents.Remove(componentID); - - var entityID = componentIDToEntityID[componentID]; - if (entityIDToComponentIDs.ContainsKey(entityID)) - { - entityIDToComponentIDs[entityID].Remove(componentID); - } - - IDToComponent.Remove(componentID); - componentIDToType.Remove(componentID); - componentIDToEntityID.Remove(componentID); - typeToComponentIDs[type].Remove(componentID); - - drawLayerManager.UnRegisterComponentWithLayer(componentID); - } - - componentsToRemove.Clear(); - } - public void RegisterDestroyedEntity(Guid entityID) { entityIDToComponentIDs.Remove(entityID); diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index 9c336df..d51c8ca 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -107,6 +107,68 @@ namespace Encompass return componentManager.GetActiveComponentByType(); } + protected Guid AddComponent(Entity entity, TComponent component) where TComponent : struct, IComponent + { + if (!writeTypes.Contains(typeof(TComponent))) + { + throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); + } + + return componentManager.AddComponent(entity.ID, component); + } + + protected Guid AddDrawComponent(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent + { + if (!writeTypes.Contains(typeof(TComponent))) + { + throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); + } + + return componentManager.AddDrawComponent(entity.ID, component, layer); + } + + protected void ActivateComponent(Guid componentID) + { + var type = componentManager.GetComponentTypeByID(componentID); + if (!writeTypes.Contains(type)) + { + throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name); + } + + componentManager.Activate(componentID); + } + + protected void DeactivateComponent(Guid componentID) + { + var type = componentManager.GetComponentTypeByID(componentID); + if (!writeTypes.Contains(type)) + { + throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name); + } + + componentManager.Deactivate(componentID); + } + + protected IEnumerable> GetComponents(Entity entity) where TComponent : struct, IComponent + { + if (!readTypes.Contains(typeof(TComponent))) + { + throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); + } + + return componentManager.GetComponentsByEntityAndType(entity.ID); + } + + protected ValueTuple GetComponent(Entity entity) where TComponent : struct, IComponent + { + return GetComponents(entity).First(); + } + + protected bool HasComponent(Entity entity) where TComponent : struct, IComponent + { + return componentManager.EntityHasComponentOfType(entity.ID); + } + internal void UpdateComponentInWorld(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent { if (!writeTypes.Contains(typeof(TComponent))) @@ -157,5 +219,16 @@ namespace Encompass { entityManager.MarkForDestroy(entityID); } + + protected void RemoveComponent(Guid componentID) + { + var type = componentManager.GetComponentTypeByID(componentID); + if (!writeTypes.Contains(type)) + { + throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name); + } + + componentManager.Remove(componentID); + } } } diff --git a/encompass-cs/Entity.cs b/encompass-cs/Entity.cs index 20b3101..fd45ad5 100644 --- a/encompass-cs/Entity.cs +++ b/encompass-cs/Entity.cs @@ -1,69 +1,14 @@ using System; -using System.Collections.Generic; -using System.Linq; namespace Encompass { public struct Entity { - public readonly Guid id; + public readonly Guid ID; - private readonly ComponentManager componentManager; - - internal Entity(Guid id, ComponentManager componentManager) + internal Entity(Guid id) { - this.id = id; - this.componentManager = componentManager; - } - - public Guid AddComponent(TComponent component) where TComponent : struct, IComponent - { - return componentManager.AddComponent(id, component); - } - - public Guid AddDrawComponent(TComponent component, int layer = 0) where TComponent : struct, IComponent - { - return componentManager.AddDrawComponent(id, component, layer); - } - - public IEnumerable> GetComponents() where TComponent : struct, IComponent - { - return componentManager.GetComponentsByEntityAndType(id); - } - - public ValueTuple GetComponent() where TComponent : struct, IComponent - { - return GetComponents().First(); - } - - public bool HasComponent() where TComponent : struct, IComponent - { - return componentManager.EntityHasComponentOfType(id); - } - - internal bool HasComponent(Type type) - { - return componentManager.EntityHasComponentOfType(id, type); - } - - public void ActivateComponent(Guid componentID) - { - componentManager.MarkForActivation(componentID); - } - - public void DeactivateComponent(Guid componentID) - { - componentManager.MarkForDeactivation(componentID); - } - - public void RemoveComponent(Guid componentID) - { - componentManager.MarkForRemoval(componentID); - } - - internal void RemoveAllComponents() - { - componentManager.RemoveAllComponentsFromEntity(id); + this.ID = id; } } } diff --git a/encompass-cs/EntityManager.cs b/encompass-cs/EntityManager.cs index f58fe19..a01969f 100644 --- a/encompass-cs/EntityManager.cs +++ b/encompass-cs/EntityManager.cs @@ -31,7 +31,7 @@ namespace Encompass public Entity CreateEntity() { var id = NextID(); - var entity = new Entity(id, componentManager); + var entity = new Entity(id); IDToEntity[id] = entity; componentManager.RegisterEntity(id); return entity; @@ -56,8 +56,7 @@ namespace Encompass { foreach (var entityID in entitiesMarkedForDestroy) { - var entity = IDToEntity[entityID]; - entity.RemoveAllComponents(); + componentManager.RemoveAllComponentsFromEntity(entityID); IDToEntity.Remove(entityID); entityToEntityTrackers.Remove(entityID); componentManager.RegisterDestroyedEntity(entityID); diff --git a/encompass-cs/Renderer.cs b/encompass-cs/Renderer.cs index 1e6dee8..d96e93e 100644 --- a/encompass-cs/Renderer.cs +++ b/encompass-cs/Renderer.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; -using System.Text; +using System.Linq; namespace Encompass { public abstract class Renderer { - private EntityManager entityManager; - private ComponentManager componentManager; + internal EntityManager entityManager; + internal ComponentManager componentManager; internal void AssignEntityManager(EntityManager entityManager) { @@ -48,5 +48,15 @@ namespace Encompass { return componentManager.GetActiveComponentByType(); } + + protected IEnumerable> GetComponents(Entity entity) where TComponent : struct, IComponent + { + return componentManager.GetComponentsByEntityAndType(entity.ID); + } + + protected ValueTuple GetComponent(Entity entity) where TComponent : struct, IComponent + { + return GetComponents(entity).First(); + } } } diff --git a/encompass-cs/World.cs b/encompass-cs/World.cs index f349877..9d9abe6 100644 --- a/encompass-cs/World.cs +++ b/encompass-cs/World.cs @@ -35,10 +35,6 @@ namespace Encompass messageManager.ClearMessages(); entityManager.DestroyMarkedEntities(); - componentManager.ActivateMarkedComponents(); - componentManager.DeactivateMarkedComponents(); - componentManager.RemoveMarkedComponents(); - entityManager.CheckEntitiesWithAddedComponents(); entityManager.CheckEntitiesWithRemovedComponents(); } diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index 3026171..4732fe4 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -41,6 +41,21 @@ namespace Encompass messageManager.AddMessage(message); } + public Guid AddComponent(Entity entity, TComponent component) where TComponent : struct, IComponent + { + return componentManager.AddComponent(entity.ID, component); + } + + public Guid AddDrawComponent(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent + { + return componentManager.AddDrawComponent(entity.ID, component, layer); + } + + public void DeactivateComponent(Guid componentID) + { + componentManager.Deactivate(componentID); + } + public Engine AddEngine(TEngine engine) where TEngine : Engine { engine.AssignEntityManager(entityManager); @@ -214,10 +229,6 @@ namespace Encompass renderManager ); - componentManager.ActivateMarkedComponents(); - componentManager.DeactivateMarkedComponents(); - componentManager.RemoveMarkedComponents(); - entityManager.CheckEntitiesWithAddedComponents(); entityManager.CheckEntitiesWithRemovedComponents(); diff --git a/encompass-cs/renderers/EntityRenderer.cs b/encompass-cs/renderers/EntityRenderer.cs index f491362..b384a8b 100644 --- a/encompass-cs/renderers/EntityRenderer.cs +++ b/encompass-cs/renderers/EntityRenderer.cs @@ -47,8 +47,8 @@ namespace Encompass private bool CheckEntity(Entity entity) { - return EntityChecker.CheckEntity(entity, componentTypes) - && entity.HasComponent(DrawComponentType); + return EntityChecker.CheckEntity(componentManager, entity, componentTypes) + && componentManager.EntityHasComponentOfType(entity.ID, DrawComponentType); } } } diff --git a/encompass-cs/utility/EntityChecker.cs b/encompass-cs/utility/EntityChecker.cs index eaabb76..75483e1 100644 --- a/encompass-cs/utility/EntityChecker.cs +++ b/encompass-cs/utility/EntityChecker.cs @@ -6,9 +6,9 @@ namespace Encompass { internal static class EntityChecker { - public static bool CheckEntity(Entity entity, IEnumerable componentTypes) + public static bool CheckEntity(ComponentManager componentManager, Entity entity, IEnumerable componentTypes) { - return componentTypes.All((componentType) => entity.HasComponent(componentType)); + return componentTypes.All((componentType) => componentManager.EntityHasComponentOfType(entity.ID, componentType)); } } } diff --git a/test/ComponentTest.cs b/test/ComponentTest.cs new file mode 100644 index 0000000..30e1ba6 --- /dev/null +++ b/test/ComponentTest.cs @@ -0,0 +1,377 @@ +using NUnit.Framework; +using FluentAssertions; + +using Encompass; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace Tests +{ + public class ComponentTests + { + struct MockComponent : IComponent + { + public string myString; + public int myInt; + } + + struct EntityMessage : IMessage + { + public Entity entity; + } + + static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>(); + static (Guid, MockComponent) gottenMockComponentIDPair; + + [Reads(typeof(EntityMessage), typeof(MockComponent))] + class GetMockComponentsEngine : Engine + { + public override void Update(double dt) + { + gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>(); + + foreach (var entityMessage in ReadMessages()) + { + gottenMockComponentIDPairs = GetComponents(entityMessage.entity); + } + } + } + + [Reads(typeof(EntityMessage), typeof(MockComponent))] + class GetMockComponentEngine : Engine + { + public override void Update(double dt) + { + foreach (var entityMessage in ReadMessages()) + { + gottenMockComponentIDPair = GetComponent(entityMessage.entity); + } + } + } + + struct AddComponentTestMessage : IMessage + { + public Entity entity; + public MockComponent mockComponent; + } + + [Reads(typeof(AddComponentTestMessage), typeof(MockComponent))] + class AddComponentEngine : Engine + { + public override void Update(double dt) + { + foreach (var addComponentTestMessage in ReadMessages()) + { + Assert.IsTrue(HasComponent(addComponentTestMessage.entity)); + Assert.That(GetComponent(addComponentTestMessage.entity).Item2, Is.EqualTo(addComponentTestMessage.mockComponent)); + } + } + } + + [Test] + public void AddComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new AddComponentEngine()); + worldBuilder.AddEngine(new GetMockComponentEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + worldBuilder.AddComponent(entity, mockComponent); + + AddComponentTestMessage addComponentTestMessage; + addComponentTestMessage.entity = entity; + addComponentTestMessage.mockComponent = mockComponent; + worldBuilder.EmitMessage(addComponentTestMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01); + } + + [Test] + public void GetComponents() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new GetMockComponentsEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponentA; + mockComponentA.myInt = 3; + mockComponentA.myString = "hello"; + + MockComponent mockComponentB; + mockComponentB.myInt = 5; + mockComponentB.myString = "wassup"; + + MockComponent mockComponentC; + mockComponentC.myInt = 1; + mockComponentC.myString = "howdy"; + + var componentAID = worldBuilder.AddComponent(entity, mockComponentA); + var componentBID = worldBuilder.AddComponent(entity, mockComponentB); + var componentCID = worldBuilder.AddComponent(entity, mockComponentC); + + EntityMessage entityMessage; + entityMessage.entity = entity; + worldBuilder.EmitMessage(entityMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01); + + gottenMockComponentIDPairs.Should().Contain((componentAID, mockComponentA)); + gottenMockComponentIDPairs.Should().Contain((componentBID, mockComponentB)); + gottenMockComponentIDPairs.Should().Contain((componentCID, mockComponentC)); + } + + [Test] + public void GetComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new GetMockComponentEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + var componentID = worldBuilder.AddComponent(entity, mockComponent); + + EntityMessage entityMessage; + entityMessage.entity = entity; + worldBuilder.EmitMessage(entityMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01); + + Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair); + } + + struct HasComponentTestMessage : IMessage + { + public Entity entity; + } + + [Reads(typeof(HasComponentTestMessage), typeof(MockComponent))] + class HasComponentTestEngine : Engine + { + public override void Update(double dt) + { + foreach (var hasComponentTestEngine in ReadMessages()) + { + Assert.IsTrue(HasComponent(hasComponentTestEngine.entity)); + } + } + } + + [Test] + public void HasComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new HasComponentTestEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + worldBuilder.AddComponent(entity, mockComponent); + + HasComponentTestMessage hasComponentTestMessage; + hasComponentTestMessage.entity = entity; + worldBuilder.EmitMessage(hasComponentTestMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01); + } + + struct HasComponentWhenInactiveTestMessage : IMessage + { + public Entity entity; + } + + [Reads(typeof(HasComponentWhenInactiveTestMessage))] + class HasComponentWhenInactiveTestEngine : Engine + { + public override void Update(double dt) + { + foreach (var hasComponentTestEngine in ReadMessages()) + { + Assert.IsFalse(HasComponent(hasComponentTestEngine.entity)); + } + } + } + + [Test] + public void HasComponentWhenInactive() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new HasComponentWhenInactiveTestEngine()); + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + var componentID = worldBuilder.AddComponent(entity, mockComponent); + + HasComponentWhenInactiveTestMessage testMessage; + testMessage.entity = entity; + worldBuilder.EmitMessage(testMessage); + + worldBuilder.DeactivateComponent(componentID); + + var world = worldBuilder.Build(); + + world.Update(0.01f); + } + + struct RemoveComponentTestMessage : IMessage + { + public Entity entity; + public Guid componentID; + } + + [Reads(typeof(RemoveComponentTestMessage), typeof(MockComponent))] + [Writes(typeof(MockComponent))] + class RemoveComponentTestEngine : Engine + { + public override void Update(double dt) + { + foreach (var removeComponentMessage in ReadMessages()) + { + RemoveComponent(removeComponentMessage.componentID); + + Assert.IsFalse(HasComponent(removeComponentMessage.entity)); + Assert.IsEmpty(GetComponents(removeComponentMessage.entity)); + } + } + } + + [Test] + public void RemoveComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new RemoveComponentTestEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + var componentID = worldBuilder.AddComponent(entity, mockComponent); + + RemoveComponentTestMessage removeComponentMessage; + removeComponentMessage.entity = entity; + removeComponentMessage.componentID = componentID; + worldBuilder.EmitMessage(removeComponentMessage); + + var world = worldBuilder.Build(); + + + world.Update(0.01f); + } + + struct ActivateComponentMessage : IMessage + { + public Entity entity; + public Guid componentID; + } + + [Reads(typeof(ActivateComponentMessage))] + [Writes(typeof(MockComponent))] + class ActivateComponentEngine : Engine + { + public override void Update(double dt) + { + foreach (var activateComponentMessage in ReadMessages()) + { + ActivateComponent(activateComponentMessage.componentID); + Assert.IsTrue(HasComponent(activateComponentMessage.entity)); + } + } + } + + [Test] + public void ActivateComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new ActivateComponentEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + var componentID = worldBuilder.AddComponent(entity, mockComponent); + + worldBuilder.DeactivateComponent(componentID); + + ActivateComponentMessage activateMessage; + activateMessage.entity = entity; + activateMessage.componentID = componentID; + worldBuilder.EmitMessage(activateMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01f); + } + + struct DeactivateComponentMessage : IMessage + { + public Entity entity; + public Guid componentID; + } + + [Reads(typeof(DeactivateComponentMessage))] + [Writes(typeof(MockComponent))] + class DeactivateComponentEngine : Engine + { + public override void Update(double dt) + { + foreach (var deactivateComponentMessage in ReadMessages()) + { + DeactivateComponent(deactivateComponentMessage.componentID); + Assert.IsFalse(HasComponent(deactivateComponentMessage.entity)); + } + } + } + + [Test] + public void DeactivateComponent() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new DeactivateComponentEngine()); + + var entity = worldBuilder.CreateEntity(); + + MockComponent mockComponent; + mockComponent.myInt = 3; + mockComponent.myString = "hello"; + + var componentID = worldBuilder.AddComponent(entity, mockComponent); + + DeactivateComponentMessage deactivateComponentMessage; + deactivateComponentMessage.entity = entity; + deactivateComponentMessage.componentID = componentID; + worldBuilder.EmitMessage(deactivateComponentMessage); + + var world = worldBuilder.Build(); + + world.Update(0.01); + } + } +} diff --git a/test/EngineTest.cs b/test/EngineTest.cs index 21a7ff9..1ae33f6 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -10,6 +10,12 @@ using Encompass.Exceptions; namespace Tests { + struct MockComponent : IComponent + { + public int myInt; + public string myString; + } + public class EngineTest { static List> resultComponents; @@ -51,11 +57,11 @@ namespace Tests mockComponentB.myInt = 1; mockComponentB.myString = "howdy"; - var componentAID = entity.AddComponent(mockComponent); - var componentBID = entity.AddComponent(mockComponentB); - var inactiveComponentAID = entity.AddComponent(mockComponent); + var componentAID = worldBuilder.AddComponent(entity, mockComponent); + var componentBID = worldBuilder.AddComponent(entity, mockComponentB); + var inactiveComponentAID = worldBuilder.AddComponent(entity, mockComponent); - entity.DeactivateComponent(inactiveComponentAID); + worldBuilder.DeactivateComponent(inactiveComponentAID); var world = worldBuilder.Build(); @@ -79,7 +85,7 @@ namespace Tests mockComponent.myInt = 0; mockComponent.myString = "hello"; - entity.AddComponent(mockComponent); + worldBuilder.AddComponent(entity, mockComponent); var world = worldBuilder.Build(); @@ -104,8 +110,8 @@ namespace Tests mockComponentB.myInt = 1; mockComponentB.myString = "howdy"; - entity.AddComponent(mockComponent); - entity.AddComponent(mockComponentB); + worldBuilder.AddComponent(entity, mockComponent); + worldBuilder.AddComponent(entity, mockComponentB); var world = worldBuilder.Build(); @@ -140,7 +146,7 @@ namespace Tests mockComponent.myInt = 0; mockComponent.myString = "hello"; - entity.AddComponent(mockComponent); + worldBuilder.AddComponent(entity, mockComponent); var world = worldBuilder.Build(); @@ -177,7 +183,7 @@ namespace Tests mockComponent.myInt = 0; mockComponent.myString = "hello"; - entity.AddComponent(mockComponent); + worldBuilder.AddComponent(entity, mockComponent); var world = worldBuilder.Build(); @@ -359,8 +365,8 @@ namespace Tests componentB.myString = "hello"; var entity = worldBuilder.CreateEntity(); - entity.AddComponent(componentA); - entity.AddComponent(componentB); + worldBuilder.AddComponent(entity, componentA); + worldBuilder.AddComponent(entity, componentB); var world = worldBuilder.Build(); world.Update(0.01f); @@ -434,11 +440,11 @@ namespace Tests mockComponent.myInt = 2; mockComponent.myString = "blah"; - entity.AddComponent(destroyerComponent); - var componentID = entity.AddComponent(mockComponent); + worldBuilder.AddComponent(entity, destroyerComponent); + var componentID = worldBuilder.AddComponent(entity, mockComponent); - entityB.AddComponent(destroyerComponent); - var componentBID = entityB.AddComponent(mockComponent); + worldBuilder.AddComponent(entityB, destroyerComponent); + var componentBID = worldBuilder.AddComponent(entityB, mockComponent); var world = worldBuilder.Build(); @@ -448,7 +454,8 @@ namespace Tests Assert.That(results, Does.Not.Contain((componentBID, mockComponent))); } - [Reads(typeof(DestroyerComponent))] + [Reads(typeof(DestroyerComponent), typeof(MockComponent))] + [Writes(typeof(MockComponent))] class DestroyAndAddComponentEngine : Engine { public override void Update(double dt) @@ -457,9 +464,9 @@ namespace Tests { var componentID = componentPair.Item1; var entity = GetEntityByComponentID(componentID); - var (id, _) = entity.GetComponent(); - entity.RemoveComponent(id); - Destroy(entity.id); + var (id, _) = GetComponent(entity); + RemoveComponent(id); + Destroy(entity.ID); } } } @@ -473,8 +480,8 @@ namespace Tests var entity = worldBuilder.CreateEntity(); - entity.AddComponent(new DestroyerComponent()); - entity.AddComponent(new MockComponent()); + worldBuilder.AddComponent(entity, new DestroyerComponent()); + worldBuilder.AddComponent(entity, new MockComponent()); var world = worldBuilder.Build(); @@ -504,7 +511,7 @@ namespace Tests component.myString = "howdy"; var entity = worldBuilder.CreateEntity(); - entity.AddComponent(component); + worldBuilder.AddComponent(entity, component); var world = worldBuilder.Build(); world.Update(0.01f); @@ -534,7 +541,7 @@ namespace Tests component.myString = "howdy"; var entity = worldBuilder.CreateEntity(); - entity.AddComponent(component); + worldBuilder.AddComponent(entity, component); var world = worldBuilder.Build(); world.Update(0.01f); @@ -565,7 +572,7 @@ namespace Tests component.myString = "howdy"; var entity = worldBuilder.CreateEntity(); - entity.AddComponent(component); + worldBuilder.AddComponent(entity, component); var world = worldBuilder.Build(); @@ -598,9 +605,9 @@ namespace Tests var entityTwo = worldBuilder.CreateEntity(); EntityIDComponent entityIDComponent; - entityIDComponent.entityID = entityTwo.id; + entityIDComponent.entityID = entityTwo.ID; - entity.AddComponent(entityIDComponent); + worldBuilder.AddComponent(entity, entityIDComponent); var world = worldBuilder.Build(); diff --git a/test/EntityRendererTest.cs b/test/EntityRendererTest.cs index 75367cf..5a52d89 100644 --- a/test/EntityRendererTest.cs +++ b/test/EntityRendererTest.cs @@ -32,27 +32,27 @@ namespace Tests TestDrawComponent testDrawComponent = default(TestDrawComponent); var entityToTrack = worldBuilder.CreateEntity(); - entityToTrack.AddComponent(aComponent); - entityToTrack.AddComponent(bComponent); - entityToTrack.AddComponent(testDrawComponent); + worldBuilder.AddComponent(entityToTrack, aComponent); + worldBuilder.AddComponent(entityToTrack, bComponent); + worldBuilder.AddComponent(entityToTrack, testDrawComponent); var entityNotToTrack = worldBuilder.CreateEntity(); - entityNotToTrack.AddComponent(aComponent); - entityNotToTrack.AddComponent(testDrawComponent); + worldBuilder.AddComponent(entityNotToTrack, aComponent); + worldBuilder.AddComponent(entityNotToTrack, testDrawComponent); var entityWithoutDrawComponent = worldBuilder.CreateEntity(); - entityWithoutDrawComponent.AddComponent(aComponent); - entityWithoutDrawComponent.AddComponent(bComponent); + worldBuilder.AddComponent(entityWithoutDrawComponent, aComponent); + worldBuilder.AddComponent(entityWithoutDrawComponent, bComponent); var world = worldBuilder.Build(); world.Update(0.01f); - Console.WriteLine(renderer.IsTracking(entityNotToTrack.id)); + Console.WriteLine(renderer.IsTracking(entityNotToTrack.ID)); - Assert.IsTrue(renderer.IsTracking(entityToTrack.id)); - Assert.IsFalse(renderer.IsTracking(entityNotToTrack.id)); - Assert.IsFalse(renderer.IsTracking(entityWithoutDrawComponent.id)); + Assert.IsTrue(renderer.IsTracking(entityToTrack.ID)); + Assert.IsFalse(renderer.IsTracking(entityNotToTrack.ID)); + Assert.IsFalse(renderer.IsTracking(entityWithoutDrawComponent.ID)); } static bool called = false; @@ -75,19 +75,17 @@ namespace Tests TestDrawComponent testDrawComponent = default(TestDrawComponent); var entity = worldBuilder.CreateEntity(); - entity.AddComponent(aComponent); - entity.AddComponent(bComponent); - var testDrawComponentID = entity.AddDrawComponent(testDrawComponent, 1); + worldBuilder.AddComponent(entity, aComponent); + worldBuilder.AddComponent(entity, bComponent); + var testDrawComponentID = worldBuilder.AddDrawComponent(entity, testDrawComponent, 1); + + worldBuilder.DeactivateComponent(testDrawComponentID); var world = worldBuilder.Build(); world.Update(0.01f); - entity.DeactivateComponent(testDrawComponentID); - - world.Update(0.01f); - - Assert.IsFalse(renderer.IsTracking(entity.id)); + Assert.IsFalse(renderer.IsTracking(entity.ID)); world.Draw(); @@ -101,7 +99,7 @@ namespace Tests { public override void Render(Entity entity) { - resultComponents = entity.GetComponents(); + resultComponents = GetComponents(entity); calledOnDraw = true; } } @@ -117,16 +115,16 @@ namespace Tests TestDrawComponent testDrawComponent; var entity = worldBuilder.CreateEntity(); - entity.AddComponent(aComponent); - entity.AddComponent(cComponent); - var testDrawComponentID = entity.AddDrawComponent(testDrawComponent, 2); + worldBuilder.AddComponent(entity, aComponent); + worldBuilder.AddComponent(entity, cComponent); + var testDrawComponentID = worldBuilder.AddDrawComponent(entity, testDrawComponent, 2); var world = worldBuilder.Build(); world.Update(0.01f); world.Draw(); - Assert.IsTrue(renderer.IsTracking(entity.id)); + Assert.IsTrue(renderer.IsTracking(entity.ID)); Assert.IsTrue(calledOnDraw); resultComponents.Should().Contain(new ValueTuple(testDrawComponentID, testDrawComponent)); } diff --git a/test/EntityTest.cs b/test/EntityTest.cs deleted file mode 100644 index bbd4d9e..0000000 --- a/test/EntityTest.cs +++ /dev/null @@ -1,172 +0,0 @@ -using NUnit.Framework; -using FluentAssertions; - -using Encompass; -using System.Collections.Generic; -using System; - -namespace Tests -{ - struct MockComponent : IComponent - { - public string myString; - public int myInt; - } - - public class EntityTest - { - [Test] - public void AddComponent() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - Assert.IsTrue(entity.HasComponent()); - Assert.That(entity.GetComponent().Item2, Is.EqualTo(mockComponent)); - } - - [Test] - public void GetComponents() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponentA; - mockComponentA.myInt = 3; - mockComponentA.myString = "hello"; - - MockComponent mockComponentB; - mockComponentB.myInt = 5; - mockComponentB.myString = "wassup"; - - MockComponent mockComponentC; - mockComponentC.myInt = 1; - mockComponentC.myString = "howdy"; - - var componentAID = entity.AddComponent(mockComponentA); - var componentBID = entity.AddComponent(mockComponentB); - var componentCID = entity.AddComponent(mockComponentC); - - var world = worldBuilder.Build(); - - var components = entity.GetComponents(); - components.Should().Contain(new ValueTuple(componentAID, mockComponentA)); - components.Should().Contain(new ValueTuple(componentBID, mockComponentB)); - components.Should().Contain(new ValueTuple(componentCID, mockComponentC)); - } - - [Test] - public void GetComponent() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - var componentID = entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - Assert.AreEqual(new ValueTuple(componentID, mockComponent), entity.GetComponent()); - } - - [Test] - public void HasComponent() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - Assert.IsTrue(entity.HasComponent()); - } - - [Test] - public void HasComponentWhenInactive() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - var componentID = entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - entity.DeactivateComponent(componentID); - - world.Update(0.01f); - - Assert.IsFalse(entity.HasComponent()); - } - - [Test] - public void RemoveComponent() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - var componentID = entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - entity.RemoveComponent(componentID); - - world.Update(0.01f); - - Assert.IsFalse(entity.HasComponent()); - Assert.IsEmpty(entity.GetComponents()); - } - - [Test] - public void ReactivateComponent() - { - var worldBuilder = new WorldBuilder(); - var entity = worldBuilder.CreateEntity(); - - MockComponent mockComponent; - mockComponent.myInt = 3; - mockComponent.myString = "hello"; - - var componentID = entity.AddComponent(mockComponent); - - var world = worldBuilder.Build(); - - entity.DeactivateComponent(componentID); - - world.Update(0.01f); - - Assert.IsFalse(entity.HasComponent()); - Assert.IsEmpty(entity.GetComponents()); - - entity.ActivateComponent(componentID); - - world.Update(0.01f); - - Assert.IsTrue(entity.HasComponent()); - Assert.IsNotEmpty(entity.GetComponents()); - } - } -} diff --git a/test/GeneralRendererTest.cs b/test/GeneralRendererTest.cs index fd0e099..497464d 100644 --- a/test/GeneralRendererTest.cs +++ b/test/GeneralRendererTest.cs @@ -32,7 +32,7 @@ namespace Tests AComponent aComponent; var entity = worldBuilder.CreateEntity(); - var componentID = entity.AddComponent(aComponent); + var componentID = worldBuilder.AddComponent(entity, aComponent); var world = worldBuilder.Build(); @@ -52,8 +52,8 @@ namespace Tests AComponent aComponentTwo; var entity = worldBuilder.CreateEntity(); - var componentID = entity.AddComponent(aComponent); - var componentTwoID = entity.AddComponent(aComponentTwo); + var componentID = worldBuilder.AddComponent(entity, aComponent); + var componentTwoID = worldBuilder.AddComponent(entity, aComponentTwo); var world = worldBuilder.Build(); world.Update(0.01f); diff --git a/test/SpawnerTest.cs b/test/SpawnerTest.cs index 446fe4e..564eeba 100644 --- a/test/SpawnerTest.cs +++ b/test/SpawnerTest.cs @@ -23,12 +23,14 @@ namespace Tests } } + [Writes(typeof(TestComponent))] class TestSpawner : Spawner { protected override void Spawn(SpawnMessageA message) { resultEntity = CreateEntity(); - resultEntity.AddComponent(new TestComponent()); + AddComponent(resultEntity, new TestComponent()); + Assert.Pass(); } } @@ -42,14 +44,6 @@ namespace Tests var world = worldBuilder.Build(); world.Update(0.01); - - Assert.That(resultEntity.HasComponent(), Is.True); - - var id = resultEntity.id; - - world.Update(0.01); - - Assert.That(resultEntity.id, Is.Not.EqualTo(id)); } } } diff --git a/test/WorldTest.cs b/test/WorldTest.cs index 675a75e..fc1b8ff 100644 --- a/test/WorldTest.cs +++ b/test/WorldTest.cs @@ -44,26 +44,26 @@ namespace Tests TestDrawComponent testDrawComponent = default(TestDrawComponent); var entity = worldBuilder.CreateEntity(); - entity.AddComponent(testComponent); - entity.AddDrawComponent(testDrawComponent, 3); + worldBuilder.AddComponent(entity, testComponent); + worldBuilder.AddDrawComponent(entity, testDrawComponent, 3); TestDrawComponent testDrawComponentTwo = default(TestDrawComponent); var entityTwo = worldBuilder.CreateEntity(); - entityTwo.AddComponent(testComponent); - entityTwo.AddDrawComponent(testDrawComponentTwo, 1); + worldBuilder.AddComponent(entityTwo, testComponent); + worldBuilder.AddDrawComponent(entityTwo, testDrawComponentTwo, 1); TestDrawComponent testDrawComponentThree = default(TestDrawComponent); var entityThree = worldBuilder.CreateEntity(); - entityThree.AddComponent(testComponent); - entityThree.AddDrawComponent(testDrawComponentThree, 5); + worldBuilder.AddComponent(entityThree, testComponent); + worldBuilder.AddDrawComponent(entityThree, testDrawComponentThree, 5); TestDrawComponent testDrawComponentFour = default(TestDrawComponent); var entityFour = worldBuilder.CreateEntity(); - entityFour.AddComponent(testComponent); - entityFour.AddDrawComponent(testDrawComponentFour, -5); + worldBuilder.AddComponent(entityFour, testComponent); + worldBuilder.AddDrawComponent(entityFour, testDrawComponentFour, -5); var world = worldBuilder.Build();