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.

312 lines
13KB

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