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.

EnginesRoot.cs 27KB

9 years ago
9 years ago
7 years ago
7 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
9 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Svelto.DataStructures;
  5. using Svelto.ECS.Internal;
  6. using Svelto.ECS.Schedulers;
  7. using Svelto.Utilities;
  8. using Svelto.WeakEvents;
  9. #if EXPERIMENTAL
  10. using Svelto.ECS.Experimental;
  11. using Svelto.ECS.Experimental.Internal;
  12. #endif
  13. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  14. using Svelto.ECS.Profiler;
  15. #endif
  16. namespace Svelto.ECS
  17. {
  18. public sealed class EnginesRoot : IEntityFunctions, IEntityFactory, IDisposable
  19. {
  20. public EnginesRoot(EntityViewSubmissionScheduler entityViewScheduler)
  21. {
  22. _entityViewEngines = new Dictionary<Type, FasterList<IHandleEntityViewEngine>>();
  23. _otherEngines = new FasterList<IEngine>();
  24. _entityViewsDB = new Dictionary<Type, ITypeSafeList>();
  25. _metaEntityViewsDB = new Dictionary<Type, ITypeSafeList>();
  26. _groupEntityViewsDB = new Dictionary<int, Dictionary<Type, ITypeSafeList>>();
  27. _entityViewsDBdic = new Dictionary<Type, ITypeSafeDictionary>();
  28. _entityViewsToAdd = new DoubleBufferedEntityViews<Dictionary<Type, ITypeSafeList>>();
  29. _metaEntityViewsToAdd = new DoubleBufferedEntityViews<Dictionary<Type, ITypeSafeList>>();
  30. _groupedEntityViewsToAdd = new DoubleBufferedEntityViews<Dictionary<int, Dictionary<Type, ITypeSafeList>>>();
  31. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  32. _addEntityViewToEngine = AddEntityViewToEngine;
  33. _removeEntityViewFromEngine = RemoveEntityViewFromEngine;
  34. #endif
  35. _engineEntityViewDB = new EngineEntityViewDB(_entityViewsDB, _entityViewsDBdic, _metaEntityViewsDB, _groupEntityViewsDB);
  36. _scheduler = entityViewScheduler;
  37. _scheduler.Schedule(new WeakAction(SubmitEntityViews));
  38. #if EXPERIMENTAL
  39. _sharedStructEntityViewLists = new SharedStructEntityViewLists();
  40. _sharedGroupedStructEntityViewLists = new SharedGroupedStructEntityViewsLists();
  41. _structEntityViewEngineType = typeof(IStructEntityViewEngine<>);
  42. _groupedStructEntityViewsEngineType = typeof(IGroupedStructEntityViewsEngine<>);
  43. _implementedInterfaceTypes = new Dictionary<Type, Type[]>();
  44. #endif
  45. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  46. UnityEngine.GameObject debugEngineObject = new UnityEngine.GameObject("Engine Debugger");
  47. debugEngineObject.gameObject.AddComponent<EngineProfilerBehaviour>();
  48. #endif
  49. }
  50. public IEntityFactory GenerateEntityFactory()
  51. {
  52. return new GenericEntityFactory(new DataStructures.WeakReference<EnginesRoot>(this));
  53. }
  54. public IEntityFunctions GenerateEntityFunctions()
  55. {
  56. return new GenericEntityFunctions(new DataStructures.WeakReference<EnginesRoot>(this));
  57. }
  58. public void BuildEntity<T>(int entityID, object[] implementors = null) where T:IEntityDescriptor, new()
  59. {
  60. EntityFactory.BuildEntityViews
  61. (entityID, _entityViewsToAdd.current, EntityDescriptorTemplate<T>.Default, implementors);
  62. }
  63. public void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptor, object[] implementors = null)
  64. {
  65. EntityFactory.BuildEntityViews
  66. (entityID, _entityViewsToAdd.current, entityDescriptor, implementors);
  67. }
  68. /// <summary>
  69. /// A meta entity is a way to manage a set of entitites that are not easily
  70. /// queriable otherwise. For example you may want to group existing entities
  71. /// by size and type and then use the meta entity entityView to manage the data
  72. /// shared among the single entities of the same type and size. This will
  73. /// prevent the scenario where the coder is forced to parse all the entities to
  74. /// find the ones of the same size and type.
  75. /// Since the entities are managed through the shared entityView, the same
  76. /// shared entityView must be found on the single entities of the same type and size.
  77. /// The shared entityView of the meta entity is then used by engines that are meant
  78. /// to manage a group of entities through a single entityView.
  79. /// The same engine can manage several meta entities entityViews too.
  80. /// The Engine manages the logic of the Meta EntityView data and other engines
  81. /// can read back this data through the normal entity as the shared entityView
  82. /// will be present in their descriptor too.
  83. /// It's a way to control a group of Entities through a entityView only.
  84. /// This set of entities can share exactly the same entityView reference if
  85. /// built through this function. In this way, if you need to set a variable
  86. /// on a group of entities, instead to inject N entityViews and iterate over
  87. /// them to set the same value, you can inject just one entityView, set the value
  88. /// and be sure that the value is shared between entities.
  89. /// </summary>
  90. /// <param name="metaEntityID"></param>
  91. /// <param name="ed"></param>
  92. /// <param name="implementors"></param>
  93. public void BuildMetaEntity<T>(int metaEntityID, object[] implementors) where T:IEntityDescriptor, new()
  94. {
  95. EntityFactory.BuildEntityViews(metaEntityID, _entityViewsToAdd.current,
  96. EntityDescriptorTemplate<T>.Default, implementors);
  97. }
  98. /// <summary>
  99. /// Using this function is like building a normal entity, but the entityViews
  100. /// are grouped by groupID to be better processed inside engines and
  101. /// improve cache locality. Only IGroupStructEntityViewWithID entityViews are grouped
  102. /// other entityViews are managed as usual.
  103. /// </summary>
  104. /// <param name="entityID"></param>
  105. /// <param name="groupID"></param>
  106. /// <param name="ed"></param>
  107. /// <param name="implementors"></param>
  108. public void BuildEntityInGroup<T>(int entityID, int groupID, object[] implementors = null) where T:IEntityDescriptor, new()
  109. {
  110. EntityFactory.BuildGroupedEntityViews(entityID, groupID,
  111. _groupedEntityViewsToAdd.current,
  112. EntityDescriptorTemplate<T>.Default,
  113. implementors);
  114. }
  115. public void BuildEntityInGroup(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, object[] implementors = null)
  116. {
  117. EntityFactory.BuildGroupedEntityViews(entityID, groupID,
  118. _groupedEntityViewsToAdd.current,
  119. entityDescriptor, implementors);
  120. }
  121. public void RemoveEntity(int entityID, IRemoveEntityComponent removeInfo)
  122. {
  123. var removeEntityImplementor = removeInfo as RemoveEntityImplementor;
  124. if (removeEntityImplementor.removeEntityInfo.isInAGroup)
  125. InternalRemove(removeEntityImplementor.removeEntityInfo.descriptor.entityViewsToBuild, entityID, removeEntityImplementor.removeEntityInfo.groupID, _entityViewsDB);
  126. else
  127. InternalRemove(removeEntityImplementor.removeEntityInfo.descriptor.entityViewsToBuild, entityID, _entityViewsDB);
  128. }
  129. public void RemoveEntity<T>(int entityID) where T : IEntityDescriptor, new()
  130. {
  131. InternalRemove(EntityDescriptorTemplate<T>.Default.descriptor.entityViewsToBuild, entityID, _entityViewsDB);
  132. }
  133. public void RemoveMetaEntity<T>(int metaEntityID) where T : IEntityDescriptor, new()
  134. {
  135. InternalRemove(EntityDescriptorTemplate<T>.Default.descriptor.entityViewsToBuild, metaEntityID, _metaEntityViewsDB);
  136. }
  137. public void RemoveEntityFromGroup<T>(int entityID, int groupID) where T : IEntityDescriptor, new()
  138. {
  139. InternalRemove(EntityDescriptorTemplate<T>.Default.descriptor.entityViewsToBuild, entityID, _groupEntityViewsDB[groupID]);
  140. }
  141. public void AddEngine(IEngine engine)
  142. {
  143. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  144. Profiler.EngineProfiler.AddEngine(engine);
  145. #endif
  146. var engineType = engine.GetType();
  147. #if EXPERIMENTAL
  148. bool engineAdded;
  149. var implementedInterfaces = engineType.GetInterfaces();
  150. CollectImplementedInterfaces(implementedInterfaces);
  151. engineAdded = CheckSpecialEngine(engine);
  152. #endif
  153. var viewEngine = engine as IHandleEntityViewEngine;
  154. if (viewEngine != null)
  155. CheckEntityViewsEngine(viewEngine, engineType);
  156. else
  157. _otherEngines.Add(engine);
  158. var queryableEntityViewEngine = engine as IQueryingEntityViewEngine;
  159. if (queryableEntityViewEngine != null)
  160. {
  161. queryableEntityViewEngine.entityViewsDB = _engineEntityViewDB;
  162. queryableEntityViewEngine.Ready();
  163. }
  164. }
  165. #if EXPERIMENTAL
  166. void CollectImplementedInterfaces(Type[] implementedInterfaces)
  167. {
  168. _implementedInterfaceTypes.Clear();
  169. var type = typeof(IHandleEntityViewEngine);
  170. for (int index = 0; index < implementedInterfaces.Length; index++)
  171. {
  172. var interfaceType = implementedInterfaces[index];
  173. if (type.IsAssignableFrom(interfaceType) == false)
  174. continue;
  175. if (false == interfaceType.IsGenericTypeEx())
  176. {
  177. continue;
  178. }
  179. var genericTypeDefinition = interfaceType.GetGenericTypeDefinition();
  180. _implementedInterfaceTypes.Add(genericTypeDefinition, interfaceType.GetGenericArguments());
  181. }
  182. }
  183. bool CheckSpecialEngine(IEngine engine)
  184. {
  185. if (_implementedInterfaceTypes.Count == 0) return false;
  186. bool engineAdded = false;
  187. if (_implementedInterfaceTypes.ContainsKey(_structEntityViewEngineType))
  188. {
  189. ((IStructEntityViewEngine)engine).CreateStructEntityViews
  190. (_sharedStructEntityViewLists);
  191. }
  192. if (_implementedInterfaceTypes.ContainsKey(_groupedStructEntityViewsEngineType))
  193. {
  194. ((IGroupedStructEntityViewsEngine)engine).CreateStructEntityViews
  195. (_sharedGroupedStructEntityViewLists);
  196. }
  197. return engineAdded;
  198. }
  199. #endif
  200. void CheckEntityViewsEngine(IEngine engine, Type engineType)
  201. {
  202. var baseType = engineType.GetBaseType();
  203. if (baseType.IsGenericTypeEx())
  204. {
  205. var genericArguments = baseType.GetGenericArguments();
  206. AddEngine(engine as IHandleEntityViewEngine, genericArguments, _entityViewEngines);
  207. #if EXPERIMENTAL
  208. var activableEngine = engine as IHandleActivableEntityEngine;
  209. if (activableEngine != null)
  210. AddEngine(activableEngine, genericArguments, _activableViewEntitiesEngines);
  211. #endif
  212. return;
  213. }
  214. throw new Exception("Not Supported Engine");
  215. }
  216. static void AddEngine<T>(T engine, Type[] types,
  217. Dictionary<Type, FasterList<T>> engines)
  218. {
  219. for (int i = 0; i < types.Length; i++)
  220. {
  221. FasterList<T> list;
  222. var type = types[i];
  223. if (engines.TryGetValue(type, out list) == false)
  224. {
  225. list = new FasterList<T>();
  226. engines.Add(type, list);
  227. }
  228. list.Add(engine);
  229. }
  230. }
  231. void AddEntityViewsToTheDBAndSuitableEngines(Dictionary<Type, ITypeSafeList> entityViewsToAdd,
  232. Dictionary<Type, ITypeSafeList> entityViewsDB)
  233. {
  234. foreach (var entityViewList in entityViewsToAdd)
  235. {
  236. AddEntityViewToDB(entityViewsDB, entityViewList);
  237. if (entityViewList.Value.isQueryiableEntityView)
  238. {
  239. AddEntityViewToEntityViewsDictionary(_entityViewsDBdic, entityViewList.Value, entityViewList.Key);
  240. }
  241. }
  242. foreach (var entityViewList in entityViewsToAdd)
  243. {
  244. if (entityViewList.Value.isQueryiableEntityView)
  245. {
  246. AddEntityViewToTheSuitableEngines(_entityViewEngines, entityViewList.Value,
  247. entityViewList.Key);
  248. }
  249. }
  250. }
  251. void AddGroupEntityViewsToTheDBAndSuitableEngines(Dictionary<int, Dictionary<Type, ITypeSafeList>> groupedEntityViewsToAdd,
  252. Dictionary<int, Dictionary<Type, ITypeSafeList>> groupEntityViewsDB,
  253. Dictionary<Type, ITypeSafeList> entityViewsDB)
  254. {
  255. foreach (var group in groupedEntityViewsToAdd)
  256. {
  257. AddEntityViewsToTheDBAndSuitableEngines(group.Value, entityViewsDB);
  258. AddEntityViewsToGroupDB(groupEntityViewsDB, @group);
  259. }
  260. }
  261. static void AddEntityViewsToGroupDB(Dictionary<int, Dictionary<Type, ITypeSafeList>> groupEntityViewsDB,
  262. KeyValuePair<int, Dictionary<Type, ITypeSafeList>> @group)
  263. {
  264. Dictionary<Type, ITypeSafeList> groupedEntityViewsByType;
  265. if (groupEntityViewsDB.TryGetValue(@group.Key, out groupedEntityViewsByType) == false)
  266. groupedEntityViewsByType = groupEntityViewsDB[@group.Key] = new Dictionary<Type, ITypeSafeList>();
  267. foreach (var entityView in @group.Value)
  268. {
  269. groupedEntityViewsByType.Add(entityView.Key, entityView.Value);
  270. }
  271. }
  272. static void AddEntityViewToDB(Dictionary<Type, ITypeSafeList> entityViewsDB, KeyValuePair<Type, ITypeSafeList> entityViewList)
  273. {
  274. ITypeSafeList dbList;
  275. if (entityViewsDB.TryGetValue(entityViewList.Key, out dbList) == false)
  276. dbList = entityViewsDB[entityViewList.Key] = entityViewList.Value.Create();
  277. dbList.AddRange(entityViewList.Value);
  278. }
  279. static void AddEntityViewToEntityViewsDictionary(Dictionary<Type, ITypeSafeDictionary> entityViewsDBdic,
  280. ITypeSafeList entityViews, Type entityViewType)
  281. {
  282. ITypeSafeDictionary entityViewsDic;
  283. if (entityViewsDBdic.TryGetValue(entityViewType, out entityViewsDic) == false)
  284. entityViewsDic = entityViewsDBdic[entityViewType] = entityViews.CreateIndexedDictionary();
  285. entityViewsDic.FillWithIndexedEntityViews(entityViews);
  286. }
  287. static void AddEntityViewToTheSuitableEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines, ITypeSafeList entityViewsList, Type entityViewType)
  288. {
  289. FasterList<IHandleEntityViewEngine> enginesForEntityView;
  290. if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView))
  291. {
  292. int viewsCount;
  293. var entityViews = entityViewsList.ToArrayFast(out viewsCount);
  294. for (int i = 0; i < viewsCount; i++)
  295. {
  296. int count;
  297. var fastList = FasterList<IHandleEntityViewEngine>.NoVirt.ToArrayFast(enginesForEntityView, out count);
  298. IEntityView entityView = entityViews[i];
  299. for (int j = 0; j < count; j++)
  300. {
  301. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  302. EngineProfiler.MonitorAddDuration(_addEntityViewToEngine, fastList[j], entityView);
  303. #else
  304. fastList[j].Add(entityView);
  305. #endif
  306. }
  307. }
  308. }
  309. }
  310. void InternalRemove(IEntityViewBuilder[] entityViewBuilders, int entityID,
  311. Dictionary<Type, ITypeSafeList> entityViewsDB)
  312. {
  313. int entityViewBuildersCount = entityViewBuilders.Length;
  314. for (int i = 0; i < entityViewBuildersCount; i++)
  315. {
  316. Type entityViewType = entityViewBuilders[i].GetEntityViewType();
  317. ITypeSafeList entityViews = entityViewsDB[entityViewType];
  318. if (entityViews.UnorderedRemove(entityID) == false)
  319. entityViewsDB.Remove(entityViewType);
  320. if (entityViews.isQueryiableEntityView)
  321. {
  322. var typeSafeDictionary = _entityViewsDBdic[entityViewType];
  323. var entityView = typeSafeDictionary.GetIndexedEntityView(entityID);
  324. if (typeSafeDictionary.Remove(entityID) == false)
  325. _entityViewsDBdic.Remove(entityViewType);
  326. RemoveEntityViewFromEngines(_entityViewEngines, entityView, entityViewType);
  327. }
  328. }
  329. }
  330. void InternalRemove(IEntityViewBuilder[] entityViewBuilders, int entityID, int groupID,
  331. Dictionary<Type, ITypeSafeList> entityViewsDB)
  332. {
  333. int entityViewBuildersCount = entityViewBuilders.Length;
  334. for (int i = 0; i < entityViewBuildersCount; i++)
  335. {
  336. Type entityViewType = entityViewBuilders[i].GetEntityViewType();
  337. Dictionary<Type, ITypeSafeList> dictionary = _groupEntityViewsDB[groupID];
  338. if (dictionary[entityViewType].UnorderedRemove(entityID) == false)
  339. dictionary.Remove(entityViewType);
  340. if (dictionary.Count == 0) _groupEntityViewsDB.Remove(groupID);
  341. }
  342. InternalRemove(entityViewBuilders, entityID, entityViewsDB);
  343. }
  344. static void RemoveEntityViewFromEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines,
  345. IEntityView entityView, Type entityViewType)
  346. {
  347. FasterList<IHandleEntityViewEngine> enginesForEntityView;
  348. if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView))
  349. {
  350. int count;
  351. var fastList = FasterList<IHandleEntityViewEngine>.NoVirt.ToArrayFast(enginesForEntityView, out count);
  352. for (int j = 0; j < count; j++)
  353. {
  354. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  355. EngineProfiler.MonitorRemoveDuration(_removeEntityViewFromEngine, fastList[j], entityView);
  356. #else
  357. fastList[j].Remove(entityView);
  358. #endif
  359. }
  360. }
  361. }
  362. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  363. static void AddEntityViewToEngine(IHandleEntityViewEngine engine, IEntityView entityView)
  364. {
  365. engine.Add(entityView);
  366. }
  367. static void RemoveEntityViewFromEngine(IHandleEntityViewEngine engine, IEntityView entityView)
  368. {
  369. engine.Remove(entityView);
  370. }
  371. #endif
  372. void SubmitEntityViews()
  373. {
  374. bool newEntityViewsHaveBeenAddedWhileIterating =
  375. _metaEntityViewsToAdd.current.Count > 0
  376. || _entityViewsToAdd.current.Count > 0
  377. || _groupedEntityViewsToAdd.current.Count > 0;
  378. int numberOfReenteringLoops = 0;
  379. while (newEntityViewsHaveBeenAddedWhileIterating)
  380. {
  381. //use other as source from now on
  382. //current will be use to write new entityViews
  383. _entityViewsToAdd.Swap();
  384. _metaEntityViewsToAdd.Swap();
  385. _groupedEntityViewsToAdd.Swap();
  386. if ( _entityViewsToAdd.other.Count > 0)
  387. AddEntityViewsToTheDBAndSuitableEngines(_entityViewsToAdd.other, _entityViewsDB);
  388. if ( _metaEntityViewsToAdd.other.Count > 0)
  389. AddEntityViewsToTheDBAndSuitableEngines(_metaEntityViewsToAdd.other, _metaEntityViewsDB);
  390. if (_groupedEntityViewsToAdd.other.Count > 0)
  391. AddGroupEntityViewsToTheDBAndSuitableEngines(_groupedEntityViewsToAdd.other, _groupEntityViewsDB, _entityViewsDB);
  392. //other can be cleared now
  393. _entityViewsToAdd.other.Clear();
  394. _metaEntityViewsToAdd.other.Clear();
  395. _groupedEntityViewsToAdd.other.Clear();
  396. //has current new entityViews?
  397. newEntityViewsHaveBeenAddedWhileIterating =
  398. _metaEntityViewsToAdd.current.Count > 0
  399. || _entityViewsToAdd.current.Count > 0
  400. || _groupedEntityViewsToAdd.current.Count > 0;
  401. if (numberOfReenteringLoops > 5)
  402. throw new Exception("possible infinite loop found creating Entities inside IEntityViewsEngine Add method, please consider building entities outside IEntityViewsEngine Add method");
  403. numberOfReenteringLoops++;
  404. }
  405. }
  406. readonly Dictionary<Type, FasterList<IHandleEntityViewEngine>> _entityViewEngines;
  407. readonly FasterList<IEngine> _otherEngines;
  408. readonly Dictionary<Type, ITypeSafeList> _entityViewsDB;
  409. readonly Dictionary<Type, ITypeSafeList> _metaEntityViewsDB;
  410. readonly Dictionary<int, Dictionary<Type, ITypeSafeList>> _groupEntityViewsDB;
  411. readonly Dictionary<Type, ITypeSafeDictionary> _entityViewsDBdic;
  412. readonly DoubleBufferedEntityViews<Dictionary<Type, ITypeSafeList>> _entityViewsToAdd;
  413. readonly DoubleBufferedEntityViews<Dictionary<Type, ITypeSafeList>> _metaEntityViewsToAdd;
  414. readonly DoubleBufferedEntityViews<Dictionary<int, Dictionary<Type, ITypeSafeList>>> _groupedEntityViewsToAdd;
  415. readonly EntityViewSubmissionScheduler _scheduler;
  416. #if EXPERIMENTAL
  417. readonly Type _structEntityViewEngineType;
  418. readonly Type _groupedStructEntityViewsEngineType;
  419. readonly SharedStructEntityViewLists _sharedStructEntityViewLists;
  420. readonly SharedGroupedStructEntityViewsLists _sharedGroupedStructEntityViewLists;
  421. readonly Dictionary<Type, Type[]> _implementedInterfaceTypes;
  422. #endif
  423. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  424. static Action<IHandleEntityViewEngine, IEntityView> _addEntityViewToEngine;
  425. static Action<IHandleEntityViewEngine, IEntityView> _removeEntityViewFromEngine;
  426. #endif
  427. readonly EngineEntityViewDB _engineEntityViewDB;
  428. class DoubleBufferedEntityViews<T> where T : class, IDictionary, new()
  429. {
  430. readonly T _entityViewsToAddBufferA = new T();
  431. readonly T _entityViewsToAddBufferB = new T();
  432. public DoubleBufferedEntityViews()
  433. {
  434. this.other = _entityViewsToAddBufferA;
  435. this.current = _entityViewsToAddBufferB;
  436. }
  437. public T other { get; private set; }
  438. public T current { get; private set; }
  439. public void Swap()
  440. {
  441. var toSwap = other;
  442. other = current;
  443. current = toSwap;
  444. }
  445. }
  446. class GenericEntityFactory : IEntityFactory
  447. {
  448. DataStructures.WeakReference<EnginesRoot> _weakEngine;
  449. public GenericEntityFactory(DataStructures.WeakReference<EnginesRoot> weakReference)
  450. {
  451. _weakEngine = weakReference;
  452. }
  453. public void BuildEntity<T>(int entityID, object[] implementors = null) where T : IEntityDescriptor, new()
  454. {
  455. _weakEngine.Target.BuildEntity<T>(entityID, implementors);
  456. }
  457. public void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptor, object[] implementors = null)
  458. {
  459. _weakEngine.Target.BuildEntity(entityID, entityDescriptor, implementors);
  460. }
  461. public void BuildMetaEntity<T>(int metaEntityID, object[] implementors = null) where T : IEntityDescriptor, new()
  462. {
  463. _weakEngine.Target.BuildMetaEntity<T>(metaEntityID, implementors);
  464. }
  465. public void BuildEntityInGroup<T>(int entityID, int groupID, object[] implementors = null) where T : IEntityDescriptor, new()
  466. {
  467. _weakEngine.Target.BuildEntityInGroup<T>(entityID, groupID, implementors);
  468. }
  469. public void BuildEntityInGroup(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, object[] implementors = null)
  470. {
  471. _weakEngine.Target.BuildEntityInGroup(entityID, groupID, entityDescriptor, implementors);
  472. }
  473. }
  474. class GenericEntityFunctions : IEntityFunctions
  475. {
  476. public GenericEntityFunctions(DataStructures.WeakReference<EnginesRoot> weakReference)
  477. {
  478. _weakReference = weakReference;
  479. }
  480. public void RemoveEntity(int entityID, IRemoveEntityComponent entityTemplate)
  481. {
  482. _weakReference.Target.RemoveEntity(entityID, entityTemplate);
  483. }
  484. public void RemoveEntity<T>(int entityID) where T : IEntityDescriptor, new()
  485. {
  486. _weakReference.Target.RemoveEntity<T>(entityID);
  487. }
  488. public void RemoveMetaEntity<T>(int metaEntityID) where T : IEntityDescriptor, new()
  489. {
  490. _weakReference.Target.RemoveEntity<T>(metaEntityID);
  491. }
  492. public void RemoveEntityFromGroup<T>(int entityID, int groupID) where T : IEntityDescriptor, new()
  493. {
  494. _weakReference.Target.RemoveEntity<T>(entityID);
  495. }
  496. readonly DataStructures.WeakReference<EnginesRoot> _weakReference;
  497. }
  498. public void Dispose()
  499. {
  500. foreach (var entity in _entityViewsDB)
  501. {
  502. if (entity.Value.isQueryiableEntityView == true)
  503. {
  504. foreach (var entityView in entity.Value)
  505. {
  506. RemoveEntityViewFromEngines(_entityViewEngines, entityView as EntityView, entity.Key);
  507. }
  508. }
  509. }
  510. foreach (var entity in _metaEntityViewsDB)
  511. {
  512. foreach (var entityView in entity.Value)
  513. {
  514. RemoveEntityViewFromEngines(_entityViewEngines, entityView as EntityView, entity.Key);
  515. }
  516. }
  517. }
  518. }
  519. }