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.Linq;
namespace Encompass {
internal class ComponentManager {
namespace Encompass
{
internal class ComponentManager
{
private Dictionary<uint, List<IComponent>> entityIDToComponents = new Dictionary<uint, List<IComponent>>();
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> componentsToRemove = new List<IComponent>();
internal void AddComponent<TComponent>(uint entityID, TComponent component) where TComponent : struct, IComponent {
if (!entityIDToComponents.ContainsKey(entityID)) {
internal void AddComponent<TComponent>(uint entityID, TComponent component) where TComponent : struct, IComponent
{
if (!entityIDToComponents.ContainsKey(entityID))
{
entityIDToComponents.Add(entityID, new List<IComponent>());
}
entityIDToComponents[entityID].Add(component);
componentToEntityID[component] = entityID;
if (!activeComponents.ContainsKey(typeof(TComponent))) {
if (!activeComponents.ContainsKey(typeof(TComponent)))
{
activeComponents.Add(typeof(TComponent), new List<IComponent>());
inactiveComponents.Add(typeof(TComponent), new List<IComponent>());
}
@ -30,30 +35,36 @@ namespace Encompass {
MarkForActivation(component);
}
internal IEnumerable<IComponent> GetComponentsByEntity(uint entityID) {
internal IEnumerable<IComponent> GetComponentsByEntity(uint 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>();
}
internal TComponent GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent {
internal TComponent GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent
{
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 active_components_by_type = GetActiveComponentsByType<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();
}
/** 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];
entityIDToComponents[entityID].Remove(originalComponent);
@ -62,31 +73,38 @@ namespace Encompass {
componentToEntityID.Remove(originalComponent);
componentToEntityID.Add(newComponent, entityID);
if (activeComponents[originalComponent.GetType()].Remove(originalComponent)) {
if (activeComponents[originalComponent.GetType()].Remove(originalComponent))
{
activeComponents[originalComponent.GetType()].Add(newComponent);
}
if (inactiveComponents[originalComponent.GetType()].Remove(originalComponent)) {
if (inactiveComponents[originalComponent.GetType()].Remove(originalComponent))
{
inactiveComponents[originalComponent.GetType()].Add(newComponent);
}
if (componentsToActivate.Remove(originalComponent)) {
if (componentsToActivate.Remove(originalComponent))
{
componentsToActivate.Add(newComponent);
}
if (componentsToDeactivate.Remove(originalComponent)) {
if (componentsToDeactivate.Remove(originalComponent))
{
componentsToDeactivate.Add(newComponent);
}
if (componentsToRemove.Remove(originalComponent)) {
if (componentsToRemove.Remove(originalComponent))
{
componentsToRemove.Add(newComponent);
}
}
internal void RemoveAllComponentsFromEntity(uint entityID) {
internal void RemoveAllComponentsFromEntity(uint entityID)
{
var components = GetComponentsByEntity(entityID);
foreach (var component in components) {
foreach (var component in components)
{
activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Remove(component);
}
@ -94,20 +112,25 @@ namespace Encompass {
entityIDToComponents.Remove(entityID);
}
internal void MarkForActivation(IComponent component) {
internal void MarkForActivation(IComponent component)
{
componentsToActivate.Add(component);
}
internal void MarkForDeactivation(IComponent component) {
internal void MarkForDeactivation(IComponent component)
{
componentsToDeactivate.Add(component);
}
internal void MarkForRemoval(IComponent component) {
internal void MarkForRemoval(IComponent component)
{
componentsToRemove.Add(component);
}
internal void ActivateComponents() {
foreach (var component in componentsToActivate) {
internal void ActivateComponents()
{
foreach (var component in componentsToActivate)
{
activeComponents[component.GetType()].Add(component);
inactiveComponents[component.GetType()].Remove(component);
}
@ -115,15 +138,19 @@ namespace Encompass {
componentsToActivate.Clear();
}
internal void DeactivateComponents() {
foreach (var component in componentsToDeactivate) {
internal void DeactivateComponents()
{
foreach (var component in componentsToDeactivate)
{
activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Add(component);
}
}
internal void RemoveComponents() {
foreach (var component in componentsToRemove) {
internal void RemoveComponents()
{
foreach (var component in componentsToRemove)
{
activeComponents[component.GetType()].Remove(component);
inactiveComponents[component.GetType()].Remove(component);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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