IMessage + formatting
parent
dadd2a2397
commit
e2ecd37556
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
namespace Encompass
|
||||
{
|
||||
public interface IMessage { }
|
||||
}
|
15
src/World.cs
15
src/World.cs
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Encompass {
|
||||
namespace Encompass
|
||||
{
|
||||
[System.AttributeUsage(System.AttributeTargets.Class)]
|
||||
public class Mutates : System.Attribute
|
||||
{
|
||||
|
|
|
@ -16,5 +16,6 @@
|
|||
<Content Include="exceptions\IllegalComponentMutationException.cs" />
|
||||
<Content Include="graph\DirectedGraph.cs" />
|
||||
<Content Include="IComponent.cs" />
|
||||
<Content Include="IMessage.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue