IMessage + formatting

pull/5/head
Evan Hemsley 2019-06-15 18:05:56 -07:00
parent dadd2a2397
commit e2ecd37556
12 changed files with 150 additions and 73 deletions

0
TODO Normal file
View File

View File

@ -2,8 +2,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Encompass { namespace Encompass
internal class ComponentManager { {
internal class ComponentManager
{
private Dictionary<uint, List<IComponent>> entityIDToComponents = new Dictionary<uint, List<IComponent>>(); private Dictionary<uint, List<IComponent>> entityIDToComponents = new Dictionary<uint, List<IComponent>>();
private Dictionary<IComponent, uint> componentToEntityID = new Dictionary<IComponent, uint>(); private Dictionary<IComponent, uint> componentToEntityID = new Dictionary<IComponent, uint>();
@ -14,15 +16,18 @@ namespace Encompass {
private List<IComponent> componentsToDeactivate = new List<IComponent>(); private List<IComponent> componentsToDeactivate = new List<IComponent>();
private List<IComponent> componentsToRemove = new List<IComponent>(); private List<IComponent> componentsToRemove = new List<IComponent>();
internal void AddComponent<TComponent>(uint entityID, TComponent component) where TComponent : struct, IComponent { internal void AddComponent<TComponent>(uint entityID, TComponent component) where TComponent : struct, IComponent
if (!entityIDToComponents.ContainsKey(entityID)) { {
if (!entityIDToComponents.ContainsKey(entityID))
{
entityIDToComponents.Add(entityID, new List<IComponent>()); entityIDToComponents.Add(entityID, new List<IComponent>());
} }
entityIDToComponents[entityID].Add(component); entityIDToComponents[entityID].Add(component);
componentToEntityID[component] = entityID; componentToEntityID[component] = entityID;
if (!activeComponents.ContainsKey(typeof(TComponent))) { if (!activeComponents.ContainsKey(typeof(TComponent)))
{
activeComponents.Add(typeof(TComponent), new List<IComponent>()); activeComponents.Add(typeof(TComponent), new List<IComponent>());
inactiveComponents.Add(typeof(TComponent), new List<IComponent>()); inactiveComponents.Add(typeof(TComponent), new List<IComponent>());
} }
@ -30,30 +35,36 @@ namespace Encompass {
MarkForActivation(component); MarkForActivation(component);
} }
internal IEnumerable<IComponent> GetComponentsByEntity(uint entityID) { internal IEnumerable<IComponent> GetComponentsByEntity(uint entityID)
{
return entityIDToComponents[entityID]; return entityIDToComponents[entityID];
} }
internal IEnumerable<TComponent> GetActiveComponentsByType<TComponent>() where TComponent : struct, IComponent { internal IEnumerable<TComponent> GetActiveComponentsByType<TComponent>() where TComponent : struct, IComponent
{
return activeComponents[typeof(TComponent)].Cast<TComponent>(); return activeComponents[typeof(TComponent)].Cast<TComponent>();
} }
internal TComponent GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent { internal TComponent GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent
{
return GetActiveComponentsByType<TComponent>().Single(); return GetActiveComponentsByType<TComponent>().Single();
} }
internal IEnumerable<TComponent> GetComponentsByEntityAndType<TComponent>(uint entityID) where TComponent : struct, IComponent { internal IEnumerable<TComponent> GetComponentsByEntityAndType<TComponent>(uint entityID) where TComponent : struct, IComponent
{
var entity_components = GetComponentsByEntity(entityID).Cast<TComponent>(); var entity_components = GetComponentsByEntity(entityID).Cast<TComponent>();
var active_components_by_type = GetActiveComponentsByType<TComponent>(); var active_components_by_type = GetActiveComponentsByType<TComponent>();
return entity_components.Intersect(active_components_by_type).Cast<TComponent>(); return entity_components.Intersect(active_components_by_type).Cast<TComponent>();
} }
internal bool EntityHasComponentOfType<TComponent>(uint entityID) where TComponent : struct, IComponent { internal bool EntityHasComponentOfType<TComponent>(uint entityID) where TComponent : struct, IComponent
{
return GetComponentsByEntityAndType<TComponent>(entityID).Any(); return GetComponentsByEntityAndType<TComponent>(entityID).Any();
} }
/** Replaces the component with another. */ /** Replaces the component with another. */
internal void UpdateComponent<TComponent>(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent { internal void UpdateComponent<TComponent>(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent
{
var entityID = componentToEntityID[originalComponent]; var entityID = componentToEntityID[originalComponent];
entityIDToComponents[entityID].Remove(originalComponent); entityIDToComponents[entityID].Remove(originalComponent);
@ -62,31 +73,38 @@ namespace Encompass {
componentToEntityID.Remove(originalComponent); componentToEntityID.Remove(originalComponent);
componentToEntityID.Add(newComponent, entityID); componentToEntityID.Add(newComponent, entityID);
if (activeComponents[originalComponent.GetType()].Remove(originalComponent)) { if (activeComponents[originalComponent.GetType()].Remove(originalComponent))
{
activeComponents[originalComponent.GetType()].Add(newComponent); activeComponents[originalComponent.GetType()].Add(newComponent);
} }
if (inactiveComponents[originalComponent.GetType()].Remove(originalComponent)) { if (inactiveComponents[originalComponent.GetType()].Remove(originalComponent))
{
inactiveComponents[originalComponent.GetType()].Add(newComponent); inactiveComponents[originalComponent.GetType()].Add(newComponent);
} }
if (componentsToActivate.Remove(originalComponent)) { if (componentsToActivate.Remove(originalComponent))
{
componentsToActivate.Add(newComponent); componentsToActivate.Add(newComponent);
} }
if (componentsToDeactivate.Remove(originalComponent)) { if (componentsToDeactivate.Remove(originalComponent))
{
componentsToDeactivate.Add(newComponent); componentsToDeactivate.Add(newComponent);
} }
if (componentsToRemove.Remove(originalComponent)) { if (componentsToRemove.Remove(originalComponent))
{
componentsToRemove.Add(newComponent); componentsToRemove.Add(newComponent);
} }
} }
internal void RemoveAllComponentsFromEntity(uint entityID) { internal void RemoveAllComponentsFromEntity(uint entityID)
{
var components = GetComponentsByEntity(entityID); var components = GetComponentsByEntity(entityID);
foreach (var component in components) { foreach (var component in components)
{
activeComponents[component.GetType()].Remove(component); activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Remove(component); inactiveComponents[component.GetType()].Remove(component);
} }
@ -94,20 +112,25 @@ namespace Encompass {
entityIDToComponents.Remove(entityID); entityIDToComponents.Remove(entityID);
} }
internal void MarkForActivation(IComponent component) { internal void MarkForActivation(IComponent component)
{
componentsToActivate.Add(component); componentsToActivate.Add(component);
} }
internal void MarkForDeactivation(IComponent component) { internal void MarkForDeactivation(IComponent component)
{
componentsToDeactivate.Add(component); componentsToDeactivate.Add(component);
} }
internal void MarkForRemoval(IComponent component) { internal void MarkForRemoval(IComponent component)
{
componentsToRemove.Add(component); componentsToRemove.Add(component);
} }
internal void ActivateComponents() { internal void ActivateComponents()
foreach (var component in componentsToActivate) { {
foreach (var component in componentsToActivate)
{
activeComponents[component.GetType()].Add(component); activeComponents[component.GetType()].Add(component);
inactiveComponents[component.GetType()].Remove(component); inactiveComponents[component.GetType()].Remove(component);
} }
@ -115,15 +138,19 @@ namespace Encompass {
componentsToActivate.Clear(); componentsToActivate.Clear();
} }
internal void DeactivateComponents() { internal void DeactivateComponents()
foreach (var component in componentsToDeactivate) { {
foreach (var component in componentsToDeactivate)
{
activeComponents[component.GetType()].Remove(component); activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Add(component); inactiveComponents[component.GetType()].Add(component);
} }
} }
internal void RemoveComponents() { internal void RemoveComponents()
foreach (var component in componentsToRemove) { {
foreach (var component in componentsToRemove)
{
activeComponents[component.GetType()].Remove(component); activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Remove(component); inactiveComponents[component.GetType()].Remove(component);
} }

View File

@ -2,57 +2,73 @@ using System;
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
namespace Encompass { namespace Encompass
public abstract class Engine { {
public abstract class Engine
{
public readonly List<Type> mutateComponentTypes = new List<Type>(); public readonly List<Type> mutateComponentTypes = new List<Type>();
private EntityManager entityManager; private EntityManager entityManager;
private ComponentManager componentManager; private ComponentManager componentManager;
public Engine() { public Engine()
{
var mutatesAttribute = this.GetType().GetCustomAttribute<Mutates>(false); var mutatesAttribute = this.GetType().GetCustomAttribute<Mutates>(false);
if (mutatesAttribute != null) { if (mutatesAttribute != null)
{
mutateComponentTypes = mutatesAttribute.mutateComponentTypes; mutateComponentTypes = mutatesAttribute.mutateComponentTypes;
} }
} }
internal void AssignEntityManager(EntityManager entityManager) { internal void AssignEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager; this.entityManager = entityManager;
} }
internal void AssignComponentManager(ComponentManager componentManager) { internal void AssignComponentManager(ComponentManager componentManager)
{
this.componentManager = componentManager; this.componentManager = componentManager;
} }
public abstract void Update(float dt); public abstract void Update(float dt);
protected Entity CreateEntity() { protected Entity CreateEntity()
{
return this.entityManager.CreateEntity(); return this.entityManager.CreateEntity();
} }
protected IEnumerable<TComponent> ReadComponents<TComponent>() where TComponent : struct, IComponent { protected IEnumerable<TComponent> ReadComponents<TComponent>() where TComponent : struct, IComponent
{
return this.componentManager.GetActiveComponentsByType<TComponent>(); return this.componentManager.GetActiveComponentsByType<TComponent>();
} }
protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent { protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent
{
return this.componentManager.GetActiveComponentByType<TComponent>(); return this.componentManager.GetActiveComponentByType<TComponent>();
} }
internal void UpdateComponentInWorld<TComponent>(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent { internal void UpdateComponentInWorld<TComponent>(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent
if (mutateComponentTypes.Contains(typeof(TComponent))) { {
if (mutateComponentTypes.Contains(typeof(TComponent)))
{
this.componentManager.UpdateComponent(originalComponent, newComponent); this.componentManager.UpdateComponent(originalComponent, newComponent);
} else { }
else
{
throw new IllegalComponentMutationException("Engine {0} tried to mutate undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); throw new IllegalComponentMutationException("Engine {0} tried to mutate undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
} }
} }
protected void UpdateComponent<TComponent>(TComponent component, Func<TComponent, TComponent> updateFunction) where TComponent : struct, IComponent { protected void UpdateComponent<TComponent>(TComponent component, Func<TComponent, TComponent> updateFunction) where TComponent : struct, IComponent
{
var updatedComponent = updateFunction(component); var updatedComponent = updateFunction(component);
this.UpdateComponentInWorld(component, updatedComponent); this.UpdateComponentInWorld(component, updatedComponent);
} }
protected void UpdateComponents<TComponent>(IEnumerable<TComponent> components, Func<TComponent, TComponent> updateFunction) where TComponent : struct, IComponent { protected void UpdateComponents<TComponent>(IEnumerable<TComponent> components, Func<TComponent, TComponent> updateFunction) where TComponent : struct, IComponent
foreach (var component in components) { {
foreach (var component in components)
{
this.UpdateComponent(component, updateFunction); this.UpdateComponent(component, updateFunction);
} }
} }

View File

@ -9,28 +9,34 @@ namespace Encompass
private ComponentManager componentManager; private ComponentManager componentManager;
internal Entity(uint id, ComponentManager componentManager) { internal Entity(uint id, ComponentManager componentManager)
{
this.id = id; this.id = id;
this.componentManager = componentManager; this.componentManager = componentManager;
} }
public void AddComponent<TComponent>(TComponent component) where TComponent : struct, IComponent { public void AddComponent<TComponent>(TComponent component) where TComponent : struct, IComponent
{
componentManager.AddComponent<TComponent>(id, component); componentManager.AddComponent<TComponent>(id, component);
} }
public IEnumerable<TComponent> GetComponents<TComponent>() where TComponent : struct, IComponent { public IEnumerable<TComponent> GetComponents<TComponent>() where TComponent : struct, IComponent
{
return componentManager.GetComponentsByEntityAndType<TComponent>(id); return componentManager.GetComponentsByEntityAndType<TComponent>(id);
} }
public TComponent GetComponent<TComponent>() where TComponent : struct, IComponent { public TComponent GetComponent<TComponent>() where TComponent : struct, IComponent
{
return GetComponents<TComponent>().First(); return GetComponents<TComponent>().First();
} }
public bool HasComponent<TComponent>() where TComponent : struct, IComponent { public bool HasComponent<TComponent>() where TComponent : struct, IComponent
{
return componentManager.EntityHasComponentOfType<TComponent>(id); return componentManager.EntityHasComponentOfType<TComponent>(id);
} }
internal void RemoveAllComponents() { internal void RemoveAllComponents()
{
componentManager.RemoveAllComponentsFromEntity(id); componentManager.RemoveAllComponentsFromEntity(id);
} }
} }

View File

@ -1,7 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Encompass { namespace Encompass
internal class EntityManager { {
internal class EntityManager
{
private uint nextID = 1; private uint nextID = 1;
private List<Entity> entities = new List<Entity>(); private List<Entity> entities = new List<Entity>();
@ -13,29 +15,36 @@ namespace Encompass {
public EntityManager( public EntityManager(
ComponentManager componentManager ComponentManager componentManager
) { )
{
this.componentManager = componentManager; this.componentManager = componentManager;
} }
public Entity CreateEntity() { public Entity CreateEntity()
{
return new Entity(NextID(), componentManager); return new Entity(NextID(), componentManager);
} }
public Entity GetEntity(uint id) { public Entity GetEntity(uint id)
{
return this.IDToEntity[id]; return this.IDToEntity[id];
} }
public void MarkForDestroy(Entity entity) { public void MarkForDestroy(Entity entity)
{
entitiesMarkedForDestroy.Add(entity); entitiesMarkedForDestroy.Add(entity);
} }
internal void DestroyMarkedEntities() { internal void DestroyMarkedEntities()
foreach (var entity in entitiesMarkedForDestroy) { {
foreach (var entity in entitiesMarkedForDestroy)
{
entity.RemoveAllComponents(); entity.RemoveAllComponents();
} }
} }
private uint NextID() { private uint NextID()
{
var id = this.nextID; var id = this.nextID;
this.nextID++; this.nextID++;
return id; return id;

View File

@ -1,4 +1,4 @@
namespace Encompass namespace Encompass
{ {
public interface IComponent {} public interface IComponent { }
} }

4
src/IMessage.cs Normal file
View File

@ -0,0 +1,4 @@
namespace Encompass
{
public interface IMessage { }
}

View File

@ -1,7 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Encompass { namespace Encompass
public class World { {
public class World
{
private List<Engine> engines; private List<Engine> engines;
private EntityManager entityManager; private EntityManager entityManager;
private ComponentManager componentManager; private ComponentManager componentManager;
@ -10,14 +12,17 @@ namespace Encompass {
List<Engine> engines, List<Engine> engines,
EntityManager entityManager, EntityManager entityManager,
ComponentManager componentManager ComponentManager componentManager
) { )
{
this.engines = engines; this.engines = engines;
this.entityManager = entityManager; this.entityManager = entityManager;
this.componentManager = componentManager; this.componentManager = componentManager;
} }
public void Update(float dt) { public void Update(float dt)
foreach (var engine in engines) { {
foreach (var engine in engines)
{
engine.Update(dt); engine.Update(dt);
} }

View File

@ -1,22 +1,27 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Encompass { namespace Encompass
public class WorldBuilder { {
public class WorldBuilder
{
private List<Engine> engines = new List<Engine>(); private List<Engine> engines = new List<Engine>();
private ComponentManager componentManager; private ComponentManager componentManager;
private EntityManager entityManager; private EntityManager entityManager;
public WorldBuilder() { public WorldBuilder()
{
componentManager = new ComponentManager(); componentManager = new ComponentManager();
entityManager = new EntityManager(componentManager); entityManager = new EntityManager(componentManager);
} }
public Entity CreateEntity() { public Entity CreateEntity()
{
return this.entityManager.CreateEntity(); return this.entityManager.CreateEntity();
} }
public Engine AddEngine<TEngine>() where TEngine : Engine, new() { public Engine AddEngine<TEngine>() where TEngine : Engine, new()
{
var engine = new TEngine(); var engine = new TEngine();
engine.AssignEntityManager(this.entityManager); engine.AssignEntityManager(this.entityManager);
@ -27,7 +32,8 @@ namespace Encompass {
return engine; return engine;
} }
public World Build() { public World Build()
{
var world = new World( var world = new World(
this.engines, this.engines,
this.entityManager, this.entityManager,

View File

@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Encompass { namespace Encompass
{
[System.AttributeUsage(System.AttributeTargets.Class)] [System.AttributeUsage(System.AttributeTargets.Class)]
public class Mutates : System.Attribute public class Mutates : System.Attribute
{ {

View File

@ -16,5 +16,6 @@
<Content Include="exceptions\IllegalComponentMutationException.cs" /> <Content Include="exceptions\IllegalComponentMutationException.cs" />
<Content Include="graph\DirectedGraph.cs" /> <Content Include="graph\DirectedGraph.cs" />
<Content Include="IComponent.cs" /> <Content Include="IComponent.cs" />
<Content Include="IMessage.cs" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,9 @@
using System; using System;
namespace Encompass { namespace Encompass
public class IllegalComponentMutationException : Exception { {
public class IllegalComponentMutationException : Exception
{
public IllegalComponentMutationException( public IllegalComponentMutationException(
string format, string format,
params object[] args params object[] args