using System; using System.Collections.Generic; using Svelto.DataStructures; using Svelto.ECS.Experimental.Internal; namespace Svelto.ECS.Experimental.Internal { public interface IStructEntityViewEngine : IEngine { void CreateStructEntityViews(SharedStructEntityViewLists sharedStructEntityViewLists); } public interface IGroupedStructEntityViewsEngine : IEngine { void CreateStructEntityViews(SharedGroupedStructEntityViewsLists sharedStructEntityViewLists); } } namespace Svelto.ECS.Experimental { public interface IGroupedEntityView { int groupID { get; set; } } /// /// The engines can receive and store IEntityViews structs /// Unboxing will happen during the Add, but the /// data will then be stored and processed as stucts /// public interface IStructEntityViewEngine : IStructEntityViewEngine where T:struct, IEntityStruct { } /// /// same as above, but the entityViews are grouped by ID /// usually the ID is the owner of the entityViews of that /// group /// public interface IGroupedStructEntityViewsEngine : IGroupedStructEntityViewsEngine where T : struct, IGroupedEntityView { void Add(ref T entityView); void Remove(ref T entityView); } public sealed class StructEntityViews where T:struct, IEntityStruct { public T[] GetList(out int numberOfItems) { numberOfItems = _internalList.Count; return _internalList.ToArrayFast(); } public StructEntityViews(SharedStructEntityViewLists container) { _internalList = SharedStructEntityViewLists.NoVirt.GetList(container); } public void Add(T entityView) { T convert = (T)entityView; _internalList.Add(convert); } readonly FasterList _internalList; } public struct StructGroupEntityViews where T : struct, IEntityView { public StructGroupEntityViews(SharedGroupedStructEntityViewsLists container) { _container = container; indices = new Dictionary(); } public void Add(int groupID, T entityView) { T convert = (T)entityView; var fasterList = (SharedGroupedStructEntityViewsLists.NoVirt.GetList(_container, groupID) as FasterList); indices[entityView.ID] = fasterList.Count; fasterList.Add(convert); } public void Remove(int groupID, T entityView) { var fasterList = (SharedGroupedStructEntityViewsLists.NoVirt.GetList(_container, groupID) as FasterList); var index = indices[entityView.ID]; indices.Remove(entityView.ID); if (fasterList.UnorderedRemoveAt(index)) indices[fasterList[index].ID] = index; } public T[] GetList(int groupID, out int numberOfItems) { var fasterList = (SharedGroupedStructEntityViewsLists.NoVirt.GetList(_container, groupID) as FasterList); return FasterList.NoVirt.ToArrayFast(fasterList, out numberOfItems); } readonly SharedGroupedStructEntityViewsLists _container; readonly Dictionary indices; } public class SharedStructEntityViewLists { internal SharedStructEntityViewLists() { _collection = new Dictionary(); } internal static class NoVirt { internal static FasterList GetList(SharedStructEntityViewLists obj) where T : struct { IFasterList list; if (obj._collection.TryGetValue(typeof(T), out list)) { return list as FasterList; } list = new FasterList(); obj._collection.Add(typeof(T), list); return (FasterList)list; } } readonly Dictionary _collection; } public class SharedGroupedStructEntityViewsLists { internal SharedGroupedStructEntityViewsLists() { _collection = new Dictionary>(); } internal static class NoVirt { internal static IFasterList GetList(SharedGroupedStructEntityViewsLists list, int groupID) where T : struct { Dictionary dic = GetGroup(list); IFasterList localList; if (dic.TryGetValue(groupID, out localList)) return localList; localList = new FasterList(); dic.Add(groupID, localList); return localList; } internal static Dictionary GetGroup(SharedGroupedStructEntityViewsLists list) where T : struct { Dictionary dic; if (list._collection.TryGetValue(typeof(T), out dic)) { return dic; } dic = new Dictionary(); list._collection.Add(typeof(T), dic); return dic; } } readonly Dictionary> _collection; } }