Merge pull request #11 from thatcosmonaut/integer_id

integer IDs and entity capacity
pull/5/head
thatcosmonaut 2019-12-21 10:57:53 -08:00 committed by GitHub
commit 2abffd1cf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 26 deletions

View File

@ -8,21 +8,16 @@ namespace Encompass
/// </summary> /// </summary>
public struct Entity : IEquatable<Entity> public struct Entity : IEquatable<Entity>
{ {
public readonly Guid ID; public readonly int ID;
internal Entity(Guid id) internal Entity(int id)
{ {
ID = id; ID = id;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (obj is Entity entity) return obj is Entity entity && Equals(entity);
{
return Equals(entity);
}
return false;
} }
public bool Equals(Entity other) public bool Equals(Entity other)

View File

@ -1,30 +1,45 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using Encompass.Exceptions;
namespace Encompass namespace Encompass
{ {
internal class EntityManager internal class EntityManager
{ {
private readonly HashSet<Guid> IDs = new HashSet<Guid>(); private readonly int entityCapacity;
private readonly IDManager idManager = new IDManager();
private readonly HashSet<int> IDs = new HashSet<int>();
private readonly HashSet<Entity> entitiesMarkedForDestroy = new HashSet<Entity>(); private readonly HashSet<Entity> entitiesMarkedForDestroy = new HashSet<Entity>();
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
public EntityManager(ComponentManager componentManager) public EntityManager(ComponentManager componentManager, int entityCapacity)
{ {
this.componentManager = componentManager; this.componentManager = componentManager;
this.entityCapacity = entityCapacity;
}
private int NextID()
{
return idManager.NextID();
} }
public Entity CreateEntity() public Entity CreateEntity()
{
if (IDs.Count < entityCapacity)
{ {
var id = NextID(); var id = NextID();
var entity = new Entity(id); var entity = new Entity(id);
IDs.Add(id); IDs.Add(id);
return entity; return entity;
} }
else
{
throw new EntityOverflowException("The number of entities has exceeded the entity capacity of {0}", entityCapacity);
}
}
public bool EntityExists(Guid id) public bool EntityExists(int id)
{ {
return IDs.Contains(id); return IDs.Contains(id);
} }
@ -40,14 +55,10 @@ namespace Encompass
{ {
componentManager.MarkAllComponentsOnEntityForRemoval(entity); componentManager.MarkAllComponentsOnEntityForRemoval(entity);
IDs.Remove(entity.ID); IDs.Remove(entity.ID);
idManager.Free(entity.ID);
} }
entitiesMarkedForDestroy.Clear(); entitiesMarkedForDestroy.Clear();
} }
private Guid NextID()
{
return Guid.NewGuid();
}
} }
} }

View File

@ -0,0 +1,12 @@
using System;
namespace Encompass.Exceptions
{
public class EntityOverflowException : Exception
{
public EntityOverflowException(
string format,
params object[] args
) : base(string.Format(format, args)) { }
}
}

28
encompass-cs/IDManager.cs Normal file
View File

@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace Encompass
{
internal class IDManager
{
int nextID = 0;
private Stack<int> availableIDs = new Stack<int>();
public int NextID()
{
if (availableIDs.Count > 0)
{
return availableIDs.Pop();
}
else
{
return nextID++;
}
}
public void Free(int ID)
{
availableIDs.Push(ID);
}
}
}

View File

@ -18,6 +18,7 @@ namespace Encompass
/// </remarks> /// </remarks>
public class WorldBuilder public class WorldBuilder
{ {
private readonly int entityCapacity;
private readonly List<Engine> engines = new List<Engine>(); private readonly List<Engine> engines = new List<Engine>();
private readonly DirectedGraph<Engine, Unit> engineGraph = GraphBuilder.DirectedGraph<Engine>(); private readonly DirectedGraph<Engine, Unit> engineGraph = GraphBuilder.DirectedGraph<Engine>();
private readonly ComponentStore startingComponentStoreForComponentManager = new ComponentStore(); private readonly ComponentStore startingComponentStoreForComponentManager = new ComponentStore();
@ -39,14 +40,15 @@ namespace Encompass
private readonly HashSet<Type> messageTypes = new HashSet<Type>(); private readonly HashSet<Type> messageTypes = new HashSet<Type>();
public WorldBuilder() public WorldBuilder(int entityCapacity = 32768)
{ {
this.entityCapacity = entityCapacity;
drawLayerManager = new DrawLayerManager(); drawLayerManager = new DrawLayerManager();
timeManager = new TimeManager(); timeManager = new TimeManager();
componentUpdateManager = new ComponentUpdateManager(); componentUpdateManager = new ComponentUpdateManager();
componentManager = new ComponentManager(drawLayerManager, componentUpdateManager); componentManager = new ComponentManager(drawLayerManager, componentUpdateManager);
messageManager = new MessageManager(timeManager); messageManager = new MessageManager(timeManager);
entityManager = new EntityManager(componentManager); entityManager = new EntityManager(componentManager, entityCapacity);
renderManager = new RenderManager(drawLayerManager); renderManager = new RenderManager(drawLayerManager);
} }
@ -402,7 +404,7 @@ namespace Encompass
var dummyDrawLayerManager = new DrawLayerManager(); var dummyDrawLayerManager = new DrawLayerManager();
var dummyComponentUpdateManager = new ComponentUpdateManager(); var dummyComponentUpdateManager = new ComponentUpdateManager();
var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, dummyComponentUpdateManager); var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, dummyComponentUpdateManager);
var dummyEntityManager = new EntityManager(dummyComponentManager); var dummyEntityManager = new EntityManager(dummyComponentManager, entityCapacity);
var dummyRenderManager = new RenderManager(dummyDrawLayerManager); var dummyRenderManager = new RenderManager(dummyDrawLayerManager);
var prepEngineOrder = new List<Engine>(); var prepEngineOrder = new List<Engine>();

View File

@ -2,6 +2,7 @@ using NUnit.Framework;
using FluentAssertions; using FluentAssertions;
using Encompass; using Encompass;
using Encompass.Exceptions;
namespace Tests namespace Tests
{ {
@ -20,5 +21,18 @@ namespace Tests
Assert.AreEqual(entity, entity); Assert.AreEqual(entity, entity);
Assert.IsTrue(entity == copyEntity); Assert.IsTrue(entity == copyEntity);
} }
[Test]
public void EntityOverflowException()
{
var worldBuilder = new WorldBuilder(16);
for (var i = 0; i < 16; i++)
{
worldBuilder.CreateEntity();
}
Assert.Throws<EntityOverflowException>(() => worldBuilder.CreateEntity());
}
} }
} }