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 /// 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); } 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 = FasterDictionary.Construct(); return stream; } FasterDictionary _streams; } }