Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
13KB

  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using System.Threading;
  4. using Svelto.Common;
  5. using Svelto.DataStructures;
  6. using Svelto.ECS.Hybrid;
  7. namespace Svelto.ECS.Internal
  8. {
  9. public sealed class ManagedTypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue>
  10. where TValue : struct, IBaseEntityComponent
  11. {
  12. static readonly Type _type = typeof(TValue);
  13. #if SLOW_SVELTO_SUBMISSION
  14. static readonly bool _hasEgid = typeof(INeedEGID).IsAssignableFrom(_type);
  15. static readonly bool _hasReference = typeof(INeedEntityReference).IsAssignableFrom(_type);
  16. #endif
  17. static readonly ThreadLocal<IEntityIDs> cachedEntityIDM =
  18. new ThreadLocal<IEntityIDs>(() => new ManagedEntityIDs());
  19. public ManagedTypeSafeDictionary(uint size)
  20. {
  21. implMgd =
  22. new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
  23. ManagedStrategy<int>>(size, Allocator.Managed);
  24. }
  25. public IEntityIDs entityIDs
  26. {
  27. get
  28. {
  29. ref var unboxed = ref Unsafe.Unbox<ManagedEntityIDs>(cachedEntityIDM.Value);
  30. unboxed.Update(implMgd.unsafeKeys.ToRealBuffer());
  31. return cachedEntityIDM.Value;
  32. }
  33. }
  34. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  35. public bool ContainsKey(uint egidEntityId)
  36. {
  37. return implMgd.ContainsKey(egidEntityId);
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public uint GetIndex(uint valueEntityId)
  41. {
  42. return implMgd.GetIndex(valueEntityId);
  43. }
  44. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  45. public ref TValue GetOrAdd(uint idEntityId)
  46. {
  47. return ref implMgd.GetOrAdd(idEntityId);
  48. }
  49. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  50. public IBuffer<TValue> GetValues(out uint count)
  51. {
  52. return implMgd.UnsafeGetValues(out count);
  53. }
  54. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  55. public ref TValue GetDirectValueByRef(uint key)
  56. {
  57. return ref implMgd.GetDirectValueByRef(key);
  58. }
  59. public ref TValue GetValueByRef(uint key)
  60. {
  61. return ref implMgd.GetValueByRef(key);
  62. }
  63. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  64. public bool Has(uint key)
  65. {
  66. return implMgd.ContainsKey(key);
  67. }
  68. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  69. public bool TryFindIndex(uint entityId, out uint index)
  70. {
  71. return implMgd.TryFindIndex(entityId, out index);
  72. }
  73. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  74. public bool TryGetValue(uint entityId, out TValue item)
  75. {
  76. return implMgd.TryGetValue(entityId, out item);
  77. }
  78. public int count
  79. {
  80. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  81. get => implMgd.count;
  82. }
  83. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  84. public ITypeSafeDictionary Create()
  85. {
  86. return TypeSafeDictionaryFactory<TValue>.Create(1);
  87. }
  88. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  89. public void Clear()
  90. {
  91. implMgd.Clear();
  92. }
  93. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  94. public void EnsureCapacity(uint size)
  95. {
  96. implMgd.EnsureCapacity(size);
  97. }
  98. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  99. public void IncreaseCapacityBy(uint size)
  100. {
  101. implMgd.IncreaseCapacityBy(size);
  102. }
  103. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  104. public void Trim()
  105. {
  106. implMgd.Trim();
  107. }
  108. public void KeysEvaluator(Action<uint> action)
  109. {
  110. foreach (var key in implMgd.keys)
  111. action(key);
  112. }
  113. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  114. public void Add(uint egidEntityId, in TValue entityComponent)
  115. {
  116. implMgd.Add(egidEntityId, entityComponent);
  117. }
  118. public void Dispose()
  119. {
  120. implMgd.Dispose();
  121. GC.SuppressFinalize(this);
  122. }
  123. /// *********************************
  124. /// the following methods are executed during the submission of entities
  125. /// *********************************
  126. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  127. public void AddEntitiesToDictionary
  128. (ITypeSafeDictionary toDictionary, ExclusiveGroupStruct groupId
  129. #if SLOW_SVELTO_SUBMISSION
  130. , in EnginesRoot.EntityReferenceMap entityLocator
  131. #endif
  132. )
  133. {
  134. TypeSafeDictionaryMethods.AddEntitiesToDictionary(implMgd, toDictionary as ITypeSafeDictionary<TValue>
  135. #if SLOW_SVELTO_SUBMISSION
  136. , entityLocator
  137. #endif
  138. , groupId);
  139. }
  140. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  141. public void RemoveEntitiesFromDictionary
  142. (FasterList<(uint, string)> infosToProcess, FasterList<uint> entityIDsAffectedByRemoval)
  143. {
  144. TypeSafeDictionaryMethods.RemoveEntitiesFromDictionary(infosToProcess, ref implMgd, entityIDsAffectedByRemoval);
  145. }
  146. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  147. public void SwapEntitiesBetweenDictionaries
  148. (FasterList<(uint, uint, string)> infosToProcess, ExclusiveGroupStruct fromGroup
  149. , ExclusiveGroupStruct toGroup, ITypeSafeDictionary toComponentsDictionary
  150. , FasterList<uint> entityIDsAffectedByRemoval)
  151. {
  152. TypeSafeDictionaryMethods.SwapEntitiesBetweenDictionaries(infosToProcess, ref implMgd
  153. , toComponentsDictionary as
  154. ITypeSafeDictionary<TValue>, fromGroup
  155. , toGroup, entityIDsAffectedByRemoval);
  156. }
  157. /// <summary>
  158. /// Execute all the engine IReactOnAdd callbacks linked to components added this submit
  159. /// </summary>
  160. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  161. public void ExecuteEnginesAddCallbacks
  162. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB
  163. , ITypeSafeDictionary toDic, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler)
  164. {
  165. TypeSafeDictionaryMethods.ExecuteEnginesAddCallbacks(ref implMgd, (ITypeSafeDictionary<TValue>)toDic
  166. , toGroup, entityComponentEnginesDB, in profiler);
  167. }
  168. /// <summary>
  169. /// Execute all the engine IReactOnSwap callbacks linked to components swapped this submit
  170. /// </summary>
  171. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  172. public void ExecuteEnginesSwapCallbacks
  173. (FasterList<(uint, uint, string)> infosToProcess
  174. , FasterList<ReactEngineContainer<IReactOnSwap>> reactiveEnginesSwap, ExclusiveGroupStruct fromGroup
  175. , ExclusiveGroupStruct toGroup, in PlatformProfiler profiler)
  176. {
  177. TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks(infosToProcess, ref implMgd, reactiveEnginesSwap
  178. , toGroup, fromGroup, in profiler);
  179. }
  180. /// <summary>
  181. /// Execute all the engine IReactOnREmove callbacks linked to components removed this submit
  182. /// </summary>
  183. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  184. public void ExecuteEnginesRemoveCallbacks
  185. (FasterList<(uint, string)> infosToProcess
  186. , FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
  187. , ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler)
  188. {
  189. TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks(infosToProcess, ref implMgd, reactiveEnginesRemove
  190. , fromGroup, in sampler);
  191. }
  192. /// <summary>
  193. /// Execute all the engine IReactOnAddEx callbacks linked to components added this submit
  194. /// </summary>
  195. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  196. public void ExecuteEnginesAddEntityCallbacksFast
  197. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd
  198. , ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler)
  199. {
  200. TypeSafeDictionaryMethods.ExecuteEnginesAddEntityCallbacksFast(
  201. reactiveEnginesAdd, groupID, rangeOfSubmittedEntitiesIndicies, entityIDs, this, profiler);
  202. }
  203. /// <summary>
  204. /// Execute all the engine IReactOnSwapEx callbacks linked to components swapped this submit
  205. /// </summary>
  206. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  207. public void ExecuteEnginesSwapCallbacksFast
  208. (FasterList<ReactEngineContainer<IReactOnSwapEx>> reactiveEnginesSwap, ExclusiveGroupStruct fromGroup
  209. , ExclusiveGroupStruct toGroup, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler sampler)
  210. {
  211. TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacksFast(reactiveEnginesSwap, fromGroup, toGroup, entityIDs
  212. , this, rangeOfSubmittedEntitiesIndicies, sampler);
  213. }
  214. /// <summary>
  215. /// Execute all the engine IReactOnRemoveEx callbacks linked to components removed this submit
  216. /// </summary>
  217. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  218. public void ExecuteEnginesRemoveCallbacksFast
  219. (FasterList<ReactEngineContainer<IReactOnRemoveEx>> reactiveEnginesRemoveEx, ExclusiveGroupStruct fromGroup
  220. , (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler sampler)
  221. {
  222. TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacksFast(reactiveEnginesRemoveEx, fromGroup
  223. , rangeOfSubmittedEntitiesIndicies, entityIDs
  224. , this, sampler);
  225. }
  226. /// <summary>
  227. /// Execute all the engine IReactOnSwap and IReactOnSwapEx callbacks linked to components swapped between
  228. /// whole groups swapped during this submit
  229. /// </summary>
  230. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  231. public void ExecuteEnginesSwapCallbacks_Group
  232. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap
  233. , FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx
  234. , ITypeSafeDictionary toDictionary, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup
  235. , in PlatformProfiler profiler)
  236. {
  237. TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks_Group(
  238. ref implMgd, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, this, reactiveEnginesSwap
  239. , reactiveEnginesSwapEx, count, entityIDs, in profiler);
  240. }
  241. /// <summary>
  242. /// Execute all the engine IReactOnRemove and IReactOnRemoveEx callbacks linked to components remove from
  243. /// whole groups removed during this submit
  244. /// </summary>
  245. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  246. public void ExecuteEnginesRemoveCallbacks_Group
  247. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
  248. , FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx
  249. , ExclusiveGroupStruct group, in PlatformProfiler profiler)
  250. {
  251. TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks_Group(
  252. ref implMgd, this, reactiveEnginesRemove, reactiveEnginesRemoveEx, count, entityIDs, group
  253. , in profiler);
  254. }
  255. /// <summary>
  256. /// Execute all the engine IReactOnDispose for eahc component registered in the DB when it's disposed of
  257. /// </summary>
  258. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  259. public void ExecuteEnginesDisposeCallbacks_Group
  260. (FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
  261. , ExclusiveGroupStruct group, in PlatformProfiler profiler)
  262. {
  263. TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(ref implMgd, engines, group, in profiler);
  264. }
  265. SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
  266. ManagedStrategy<int>> implMgd;
  267. }
  268. }