Mirror of Svelto.ECS because we're a fan of it
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

313 строки
14KB

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