using System;
using Svelto.DataStructures;
namespace Svelto.ECS
{
///
/// I eventually realised that, with the ECS design, no form of engines (systems) communication other
/// than polling entity components is effective.
/// The only purpose of this publisher/consumer model is to let two enginesroots communicate with each other
/// through a thread safe ring buffer.
/// The engines root A publishes entities.
/// The engines root B can consume those entities at any time, as they will be a copy of the original
/// entities and won't point directly to the database of the engines root A
///
struct EntitiesStreams : IDisposable
{
internal Consumer GenerateConsumer(string name, uint capacity)
where T : unmanaged, IBaseEntityComponent
{
if (_streams.ContainsKey(TypeRefWrapper.wrapper) == false)
_streams[TypeRefWrapper.wrapper] = new EntityStream();
return (_streams[TypeRefWrapper.wrapper] as EntityStream).GenerateConsumer(name, capacity);
}
public Consumer GenerateConsumer(ExclusiveGroupStruct group, string name, uint capacity)
where T : unmanaged, IBaseEntityComponent
{
if (_streams.ContainsKey(TypeRefWrapper.wrapper) == false)
_streams[TypeRefWrapper.wrapper] = new EntityStream();
var typeSafeStream = (EntityStream) _streams[TypeRefWrapper.wrapper];
return typeSafeStream.GenerateConsumer(group, name, capacity);
}
internal void PublishEntity(ref T entity, EGID egid) where T : unmanaged, IBaseEntityComponent
{
if (_streams.TryGetValue(TypeRefWrapper.wrapper, out var typeSafeStream))
(typeSafeStream as EntityStream).PublishEntity(ref entity, egid);
else
Console.LogDebug("No Consumers are waiting for this entity to change ", typeof(T));
}
public void Dispose()
{
foreach (var stream in _streams)
stream.value.Dispose();
}
public static EntitiesStreams Create()
{
var stream = new EntitiesStreams();
stream._streams = FasterDictionary.Construct();
return stream;
}
FasterDictionary _streams;
}
}