AddComponent for newly created Entities

pull/2/head
Evan Hemsley 2020-03-17 15:29:16 -07:00
parent 62a717cfbb
commit 511a05f18e
4 changed files with 128 additions and 4 deletions

View File

@ -73,7 +73,14 @@ namespace Encompass
return false;
}
public bool UpdateComponent<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
internal void AddImmediateComponent<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
{
immediateComponentStore.Set(entityID, component);
replayStore.Set(entityID, component);
upToDateComponentStore.Set(entityID, component);
}
internal bool UpdateComponent<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
{
var result = upToDateComponentStore.Set(entityID, component, priority);
if (result)
@ -83,6 +90,12 @@ namespace Encompass
return result;
}
internal void AddComponent<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
{
upToDateComponentStore.Set(entityID, component);
replayStore.Set(entityID, component);
}
// existing or immediate reads
internal IEnumerable<(TComponent, int)> ReadExistingAndImmediateComponentsByType<TComponent>() where TComponent : struct, IComponent

View File

@ -173,6 +173,11 @@ namespace Encompass
return _newlyCreatedEntities.Contains(entityID);
}
internal void ClearNewlyCreatedEntities()
{
_newlyCreatedEntities.Clear();
}
/// <summary>
/// Runs once per World update with the calculated delta-time.
/// </summary>
@ -478,7 +483,16 @@ namespace Encompass
throw new IllegalWriteException("AddComponent used on Entity that was not created in this context. Use SetComponent instead.");
}
componentManager.AddComponent(entity.ID, component);
if (writeImmediateTypes.Contains(typeof(TComponent)))
{
componentManager.AddImmediateComponent(entity.ID, component);
trackingManager.ImmediateUpdateTracking(entity.ID, typeof(TComponent));
}
else
{
componentManager.AddComponent(entity.ID, component);
}
trackingManager.RegisterAddition(entity.ID, typeof(TComponent));
if (component is IDrawableComponent drawableComponent)

View File

@ -54,6 +54,8 @@ namespace Encompass
{
engine.Update(dt);
}
engine.ClearNewlyCreatedEntities();
}
messageManager.ClearMessages();

View File

@ -415,8 +415,8 @@ namespace Tests
Assert.Throws<IllegalReadException>(() => world.Update(0.01f));
}
struct EntityMessage : IMessage, IHasEntity
{
struct EntityMessage : IMessage, IHasEntity
{
public EntityMessage(Entity entity, int myInt)
{
Entity = entity;
@ -1240,6 +1240,101 @@ namespace Tests
undilatedDeltaTime.Should().Be(0.5);
}
class AddComponentWithoutPriorityEngine : Engine
{
public override void Update(double dt)
{
var entity = CreateEntity();
AddComponent(entity, new MockComponent());
var entityB = CreateEntity();
AddComponent(entityB, new MockComponent());
}
}
[Test]
public void AddComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentWithoutPriorityEngine());
worldBuilder.AddEngine(new ReadComponentsTestEngine());
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01);
resultComponents.Should().HaveCount(2);
world.Update(0.01);
resultComponents.Should().HaveCount(4);
}
[Reads(typeof(MockComponent))]
class AddComponentToPreviouslyExistingEntityEngine : Engine
{
public override void Update(double dt)
{
var (component, entity) = ReadComponentIncludingEntity<MockComponent>();
AddComponent(entity, new MockComponent());
}
}
[Test]
public void AddComponentToPreviouslyExistingEntityTest()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentToPreviouslyExistingEntityEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.Throws<IllegalWriteException>(() => world.Update(0.01));
}
[WritesImmediate(typeof(MockComponentB))]
class AddImmediateComponentEngine : Engine
{
public override void Update(double dt)
{
var entity = CreateEntity();
AddComponent(entity, new MockComponentB(5));
}
}
[ReadsImmediate(typeof(MockComponentB))]
class ReadImmediateComponentEngine : Engine
{
public override void Update(double dt)
{
var (component, entity) = ReadComponentIncludingEntity<MockComponentB>();
getComponentResult = component;
}
}
[Test]
public void AddImmediateComponentTest()
{
getComponentResult = default(MockComponentB);
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddImmediateComponentEngine());
worldBuilder.AddEngine(new ReadImmediateComponentEngine());
var world = worldBuilder.Build();
world.Update(0.01);
getComponentResult.Should().Be(new MockComponentB(5));
}
public class QueryTests
{
struct MockComponentB : IComponent { }