using System;
using Svelto.DataStructures;
namespace Svelto.ECS
{
///
/// I eventually realised that, with the ECS design, no form of communication other than polling entity components can
/// exist.
/// Using groups, you can have always an optimal set of entity components to poll. However EntityStreams
/// can be useful if:
/// - you need to react on seldom entity changes, usually due to user events
/// - you want engines to be able to track entity changes
/// - you want a thread-safe way to read entity states, which includes all the state changes and not the last
/// one only
/// - you want to communicate between EnginesRoots
///
internal struct EntitiesStreams : IDisposable
{
internal Consumer GenerateConsumer(string name, uint capacity)
where T : unmanaged, IEntityComponent
{
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, IEntityComponent
{
if (_streams.ContainsKey(TypeRefWrapper.wrapper) == false)
_streams[TypeRefWrapper.wrapper] = new EntityStream();
var typeSafeStream = (EntityStream) _streams[TypeRefWrapper.wrapper];
return typeSafeStream.GenerateConsumer(group, name, capacity);
}
#if later
public ThreadSafeNativeEntityStream GenerateThreadSafePublisher(EntitiesDB entitiesDB) where T: unmanaged, IEntityComponent
{
var threadSafeNativeEntityStream = new ThreadSafeNativeEntityStream(entitiesDB);
_streams[TypeRefWrapper.wrapper] = threadSafeNativeEntityStream;
return threadSafeNativeEntityStream;
}
#endif
internal void PublishEntity(ref T entity, EGID egid) where T : unmanaged, IEntityComponent
{
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 = ManagedSveltoDictionary.Create();
return stream;
}
ManagedSveltoDictionary _streams;
}
}