message read checks + started AddComponent
parent
c1e1f7f5ca
commit
77272f10d7
2
TODO
2
TODO
|
@ -5,7 +5,5 @@
|
|||
|
||||
- auto destroy entities that no longer have components
|
||||
|
||||
- fast lookup for messages that contain entity references instead of `Where` loop?
|
||||
|
||||
- look at test coverage
|
||||
- docs
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
private HashSet<int> _newlyCreatedEntities = new HashSet<int>();
|
||||
|
||||
protected Engine()
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
|
@ -158,6 +160,19 @@ namespace Encompass
|
|||
this.trackingManager = trackingManager;
|
||||
}
|
||||
|
||||
internal void CheckMessageRead<TMessage>() where TMessage : struct, IMessage
|
||||
{
|
||||
if (!receiveTypes.Contains(typeof(TMessage)))
|
||||
{
|
||||
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||
}
|
||||
}
|
||||
|
||||
private bool EntityCreatedThisFrame(int entityID)
|
||||
{
|
||||
return _newlyCreatedEntities.Contains(entityID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs once per World update with the calculated delta-time.
|
||||
/// </summary>
|
||||
|
@ -169,7 +184,9 @@ namespace Encompass
|
|||
/// </summary>
|
||||
protected Entity CreateEntity()
|
||||
{
|
||||
return entityManager.CreateEntity();
|
||||
var entity = entityManager.CreateEntity();
|
||||
_newlyCreatedEntities.Add(entity.ID);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -448,6 +465,28 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An alternative to SetComponent that can be used for new Entities and does not require setting write priority.
|
||||
/// </summary>
|
||||
/// <exception cref="Encompass.Exceptions.IllegalWriteException">
|
||||
/// Thrown when the Engine does not declare that it Writes the given Component Type.
|
||||
/// </exception>
|
||||
protected void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||
{
|
||||
if (!_newlyCreatedEntities.Contains(entity.ID))
|
||||
{
|
||||
throw new IllegalWriteException("AddComponent used on Entity that was not created in this context. Use SetComponent instead.");
|
||||
}
|
||||
|
||||
componentManager.AddComponent(entity.ID, component);
|
||||
trackingManager.RegisterAddition(entity.ID, typeof(TComponent));
|
||||
|
||||
if (component is IDrawableComponent drawableComponent)
|
||||
{
|
||||
componentManager.RegisterDrawableComponent(entity.ID, component, drawableComponent.Layer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Message.
|
||||
/// </summary>
|
||||
|
@ -490,11 +529,7 @@ namespace Encompass
|
|||
/// </exception>
|
||||
protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
|
||||
{
|
||||
if (!receiveTypes.Contains(typeof(TMessage)))
|
||||
{
|
||||
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||
}
|
||||
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.GetMessagesByType<TMessage>();
|
||||
}
|
||||
|
||||
|
@ -506,6 +541,7 @@ namespace Encompass
|
|||
/// </exception>
|
||||
protected TMessage ReadMessage<TMessage>() where TMessage : struct, IMessage
|
||||
{
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.First<TMessage>();
|
||||
}
|
||||
|
||||
|
@ -517,11 +553,7 @@ namespace Encompass
|
|||
/// </exception>
|
||||
protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage
|
||||
{
|
||||
if (!receiveTypes.Contains(typeof(TMessage)))
|
||||
{
|
||||
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", GetType().Name, typeof(TMessage).Name);
|
||||
}
|
||||
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.Any<TMessage>();
|
||||
}
|
||||
|
||||
|
@ -648,18 +680,33 @@ namespace Encompass
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Efficiently reads Messages of a given type that all reference the same Entity.
|
||||
/// Efficiently reads Messages of a given type that all reference the given Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The Message subtype.</typeparam>
|
||||
/// <param name="entity">The entity that all messages in the IEnumerable refer to.</param>
|
||||
/// <returns></returns>
|
||||
protected IEnumerable<TMessage> ReadMessagesWithEntity<TMessage>(Entity entity) where TMessage : struct, IMessage, IHasEntity
|
||||
{
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.WithEntity<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Efficiently reads a single Message of a given type that references a given Entity.
|
||||
/// It is recommended to use this method in conjunction with SomeMessageWithEntity to prevent errors.
|
||||
/// </summary>
|
||||
protected TMessage ReadMessageWithEntity<TMessage>(Entity entity) where TMessage : struct, IMessage, IHasEntity
|
||||
{
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.WithEntitySingular<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Efficiently checks if any Message of a given type referencing a given Entity exists.
|
||||
/// </summary>
|
||||
protected bool SomeMessageWithEntity<TMessage>(Entity entity) where TMessage : struct, IMessage, IHasEntity
|
||||
{
|
||||
CheckMessageRead<TMessage>();
|
||||
return messageManager.SomeWithEntity<TMessage>(entity.ID);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Encompass
|
|||
private readonly int entityCapacity;
|
||||
private readonly IDManager idManager = new IDManager();
|
||||
private readonly HashSet<int> IDs = new HashSet<int>();
|
||||
|
||||
|
||||
private readonly HashSet<int> entitiesMarkedForDestroy = new HashSet<int>();
|
||||
|
||||
private readonly ComponentManager componentManager;
|
||||
|
|
|
@ -57,6 +57,13 @@ namespace Encompass
|
|||
return messageStore.WithEntity<TMessage>(entityID);
|
||||
}
|
||||
|
||||
internal TMessage WithEntitySingular<TMessage>(int entityID) where TMessage : struct, IMessage, IHasEntity
|
||||
{
|
||||
var enumerator = messageStore.WithEntity<TMessage>(entityID).GetEnumerator();
|
||||
enumerator.MoveNext();
|
||||
return enumerator.Current;
|
||||
}
|
||||
|
||||
internal bool SomeWithEntity<TMessage>(int entityID) where TMessage : struct, IMessage, IHasEntity
|
||||
{
|
||||
return messageStore.SomeWithEntity<TMessage>(entityID);
|
||||
|
|
Loading…
Reference in New Issue