starting replay system to avoid replaying every component every frame
parent
1eb72874c1
commit
a8669a6c67
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Encompass
|
||||||
|
{
|
||||||
|
internal class ComponentDeltaStore : ComponentStore
|
||||||
|
{
|
||||||
|
private readonly Dictionary<Type, Replayer> _replayers = new Dictionary<Type, Replayer>();
|
||||||
|
private readonly HashSet<Replayer> _currentReplayers = new HashSet<Replayer>();
|
||||||
|
|
||||||
|
public IEnumerable<Replayer> CurrentReplayers { get { return _currentReplayers; } }
|
||||||
|
|
||||||
|
public ComponentDeltaStore(Dictionary<Type, int> typeToIndex) : base(typeToIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RegisterComponentType<TComponent>()
|
||||||
|
{
|
||||||
|
base.RegisterComponentType<TComponent>();
|
||||||
|
if (!_replayers.ContainsKey(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
_replayers.Add(typeof(TComponent), new Replayer<TComponent>(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Set<TComponent>(int entityID, TComponent component, int priority)
|
||||||
|
{
|
||||||
|
var result = base.Set(entityID, component, priority);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
var replayer = _replayers[typeof(TComponent)];
|
||||||
|
_currentReplayers.Add(replayer);
|
||||||
|
replayer.UnMarkRemoval(entityID);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Remove<TComponent>(int entityID, int priority)
|
||||||
|
{
|
||||||
|
var result = base.Remove<TComponent>(entityID, priority);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
var replayer = _replayers[typeof(TComponent)];
|
||||||
|
_currentReplayers.Add(replayer);
|
||||||
|
replayer.MarkRemoval(entityID);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ClearAll()
|
||||||
|
{
|
||||||
|
base.ClearAll();
|
||||||
|
foreach (var replayer in _currentReplayers)
|
||||||
|
{
|
||||||
|
replayer.Clear();
|
||||||
|
}
|
||||||
|
_currentReplayers.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
|
public virtual void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (!Stores.ContainsKey(typeof(TComponent)))
|
if (!Stores.ContainsKey(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,7 @@ namespace Encompass
|
||||||
ComponentBitSet.Set<TComponent>(entityID);
|
ComponentBitSet.Set<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Set<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
|
public virtual bool Set<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (Lookup<TComponent>().Set(entityID, component, priority))
|
if (Lookup<TComponent>().Set(entityID, component, priority))
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,7 @@ namespace Encompass
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove<TComponent>(int entityID, int priority) where TComponent : struct, IComponent
|
public virtual bool Remove<TComponent>(int entityID, int priority) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (Lookup<TComponent>().Remove(entityID, priority))
|
if (Lookup<TComponent>().Remove(entityID, priority))
|
||||||
{
|
{
|
||||||
|
@ -123,7 +123,7 @@ namespace Encompass
|
||||||
Lookup<TComponent>().Clear();
|
Lookup<TComponent>().Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearAll()
|
public virtual void ClearAll()
|
||||||
{
|
{
|
||||||
ComponentBitSet.Clear();
|
ComponentBitSet.Clear();
|
||||||
foreach (var store in Stores.Values)
|
foreach (var store in Stores.Values)
|
||||||
|
@ -137,5 +137,13 @@ namespace Encompass
|
||||||
(Stores, other.Stores) = (other.Stores, Stores);
|
(Stores, other.Stores) = (other.Stores, Stores);
|
||||||
(ComponentBitSet, other.ComponentBitSet) = (other.ComponentBitSet, ComponentBitSet);
|
(ComponentBitSet, other.ComponentBitSet) = (other.ComponentBitSet, ComponentBitSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateUsing(ComponentDeltaStore delta)
|
||||||
|
{
|
||||||
|
foreach (var replayer in delta.CurrentReplayers)
|
||||||
|
{
|
||||||
|
replayer.Replay(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Encompass
|
||||||
|
{
|
||||||
|
internal abstract class Replayer
|
||||||
|
{
|
||||||
|
public abstract void Replay(ComponentStore store);
|
||||||
|
public abstract void MarkRemoval(int entityID);
|
||||||
|
public abstract void UnMarkRemoval(int entityID);
|
||||||
|
public abstract void Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Replayer<TComponent> : Replayer where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
private readonly ComponentDeltaStore _deltaStore;
|
||||||
|
private readonly HashSet<int> _removals = new HashSet<int>();
|
||||||
|
|
||||||
|
public Replayer(ComponentDeltaStore componentStore)
|
||||||
|
{
|
||||||
|
_deltaStore = componentStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Replay(ComponentStore store)
|
||||||
|
{
|
||||||
|
foreach (var (component, entityID) in _deltaStore.All<TComponent>())
|
||||||
|
{
|
||||||
|
store.Set(entityID, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var entityID in _removals)
|
||||||
|
{
|
||||||
|
store.ForceRemove<TComponent>(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Clear()
|
||||||
|
{
|
||||||
|
_removals.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MarkRemoval(int entityID)
|
||||||
|
{
|
||||||
|
_removals.Add(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UnMarkRemoval(int entityID)
|
||||||
|
{
|
||||||
|
_removals.Remove(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ namespace Encompass
|
||||||
private readonly DrawLayerManager drawLayerManager;
|
private readonly DrawLayerManager drawLayerManager;
|
||||||
|
|
||||||
private readonly ComponentStore existingComponentStore;
|
private readonly ComponentStore existingComponentStore;
|
||||||
private readonly ComponentStore immediateComponentStore;
|
private readonly ComponentDeltaStore immediateComponentStore;
|
||||||
private ComponentStore upToDateComponentStore;
|
private ComponentStore upToDateComponentStore;
|
||||||
|
|
||||||
public Dictionary<Type, int> TypeToIndex { get; }
|
public Dictionary<Type, int> TypeToIndex { get; }
|
||||||
|
@ -22,7 +22,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
this.drawLayerManager = drawLayerManager;
|
this.drawLayerManager = drawLayerManager;
|
||||||
existingComponentStore = new ComponentStore(typeToIndex);
|
existingComponentStore = new ComponentStore(typeToIndex);
|
||||||
immediateComponentStore = new ComponentStore(typeToIndex);
|
immediateComponentStore = new ComponentDeltaStore(typeToIndex);
|
||||||
upToDateComponentStore = new ComponentStore(typeToIndex);
|
upToDateComponentStore = new ComponentStore(typeToIndex);
|
||||||
TypeToIndex = typeToIndex;
|
TypeToIndex = typeToIndex;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace Encompass
|
||||||
internal void WriteComponents()
|
internal void WriteComponents()
|
||||||
{
|
{
|
||||||
SetComponentStore(upToDateComponentStore);
|
SetComponentStore(upToDateComponentStore);
|
||||||
upToDateComponentStore.ClearAll();
|
upToDateComponentStore.UpdateUsing(immediateComponentStore);
|
||||||
immediateComponentStore.ClearAll();
|
immediateComponentStore.ClearAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,14 +250,6 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<(TComponent, Entity)> InternalRead<TComponent>() where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
foreach (var (component, id) in componentManager.GetComponentsIncludingEntity<TComponent>())
|
|
||||||
{
|
|
||||||
yield return (component, entityManager.GetEntity(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private (TComponent, int) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent
|
private (TComponent, int) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var immediateRead = readImmediateTypes.Contains(typeof(TComponent));
|
var immediateRead = readImmediateTypes.Contains(typeof(TComponent));
|
||||||
|
@ -490,11 +482,6 @@ namespace Encompass
|
||||||
messageManager.AddMessageIgnoringTimeDilation(message, time);
|
messageManager.AddMessageIgnoringTimeDilation(message, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddExistingComponent<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
componentManager.AddExistingComponent(entityID, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads all messages of the specified Type.
|
/// Reads all messages of the specified Type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
namespace Encompass
|
|
||||||
{
|
|
||||||
internal class ComponentEmitter<TComponent> : Engine where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
public override void Update(double dt)
|
|
||||||
{
|
|
||||||
foreach (var (component, entity) in InternalRead<TComponent>())
|
|
||||||
{
|
|
||||||
AddExistingComponent(entity.ID, component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -371,10 +371,6 @@ namespace Encompass
|
||||||
var method = typeof(WorldBuilder).GetMethod("RegisterComponentType", BindingFlags.NonPublic | BindingFlags.Instance);
|
var method = typeof(WorldBuilder).GetMethod("RegisterComponentType", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
var generic = method.MakeGenericMethod(registeredComponentType);
|
var generic = method.MakeGenericMethod(registeredComponentType);
|
||||||
generic.Invoke(this, null);
|
generic.Invoke(this, null);
|
||||||
|
|
||||||
var emitterEngine = (Engine)Activator.CreateInstance(typeof(ComponentEmitter<>).MakeGenericType(registeredComponentType));
|
|
||||||
AddEngine(emitterEngine);
|
|
||||||
engineOrder.Add(emitterEngine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PreloadJIT(componentTypesToRegister, messageTypes);
|
PreloadJIT(componentTypesToRegister, messageTypes);
|
||||||
|
@ -444,15 +440,6 @@ namespace Encompass
|
||||||
var drawLayerManagerRegisterGenericMethod = drawLayerManagerRegisterMethod.MakeGenericMethod(type);
|
var drawLayerManagerRegisterGenericMethod = drawLayerManagerRegisterMethod.MakeGenericMethod(type);
|
||||||
drawLayerManagerRegisterGenericMethod.Invoke(dummyDrawLayerManager, null);
|
drawLayerManagerRegisterGenericMethod.Invoke(dummyDrawLayerManager, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var emitterEngine = (Engine)Activator.CreateInstance(typeof(ComponentEmitter<>).MakeGenericType(type));
|
|
||||||
emitterEngine.AssignEntityManager(dummyEntityManager);
|
|
||||||
emitterEngine.AssignComponentManager(dummyComponentManager);
|
|
||||||
emitterEngine.AssignMessageManager(dummyMessageManager);
|
|
||||||
emitterEngine.AssignTimeManager(dummyTimeManager);
|
|
||||||
emitterEngine.AssignTrackingManager(dummyTrackingManager);
|
|
||||||
|
|
||||||
prepEngineOrder.Add(emitterEngine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prepEngineOrder.Add(uberEngine);
|
prepEngineOrder.Add(uberEngine);
|
||||||
|
|
Loading…
Reference in New Issue