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.Engines.cs 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using System.Collections.Generic;
  3. using Svelto.DataStructures;
  4. using Svelto.DataStructures.Experimental;
  5. using Svelto.ECS.Internal;
  6. using Svelto.ECS.Schedulers;
  7. using Svelto.WeakEvents;
  8. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  9. using Svelto.ECS.Profiler;
  10. #endif
  11. namespace Svelto.ECS
  12. {
  13. public partial class EnginesRoot : IDisposable
  14. {
  15. static EnginesRoot()
  16. {
  17. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  18. /// <summary>
  19. /// I still need to find a good solution for this. Need to move somewhere else
  20. /// </summary>
  21. UnityEngine.GameObject debugEngineObject = new UnityEngine.GameObject("Svelto.ECS.Profiler");
  22. debugEngineObject.gameObject.AddComponent<EngineProfilerBehaviour>();
  23. UnityEngine.GameObject.DontDestroyOnLoad(debugEngineObject);
  24. #endif
  25. }
  26. /// <summary>
  27. /// Engines root contextualize your engines and entities. You don't need to limit yourself to one EngineRoot
  28. /// as multiple engines root could promote separation of scopes. The EntitySubmissionScheduler checks
  29. /// periodically if new entity must be submitted to the database and the engines. It's an external
  30. /// dependencies to be independent by the running platform as the user can define it.
  31. /// The EntitySubmissionScheduler cannot hold an EnginesRoot reference, that's why
  32. /// it must receive a weak reference of the EnginesRoot callback.
  33. /// </summary>
  34. public EnginesRoot(EntitySubmissionScheduler entityViewScheduler)
  35. {
  36. _entitiesOperations = new FasterList<EntitySubmitOperation>();
  37. _entityEngines = new Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>>();
  38. _otherEngines = new FasterList<IEngine>();
  39. _disposableEngines = new FasterList<IDisposable>();
  40. _groupEntityDB = new FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>();
  41. _groupedGroups = new Dictionary<Type, FasterDictionary<int, ITypeSafeDictionary>>();
  42. _groupedEntityToAdd = new DoubleBufferedEntitiesToAdd<FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>>();
  43. _DB = new EntitiesDB(_groupEntityDB, _groupedGroups);
  44. _scheduler = entityViewScheduler;
  45. _scheduler.Schedule(new WeakAction(SubmitEntityViews));
  46. }
  47. public void AddEngine(IEngine engine)
  48. {
  49. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  50. Profiler.EngineProfiler.AddEngine(engine);
  51. #endif
  52. var viewEngine = engine as IHandleEntityViewEngineAbstracted;
  53. if (viewEngine != null)
  54. CheckEntityViewsEngine(viewEngine);
  55. else
  56. _otherEngines.Add(engine);
  57. if (engine is IDisposable)
  58. _disposableEngines.Add(engine as IDisposable);
  59. var queryableEntityViewEngine = engine as IQueryingEntitiesEngine;
  60. if (queryableEntityViewEngine != null)
  61. {
  62. queryableEntityViewEngine.entitiesDB = _DB;
  63. queryableEntityViewEngine.Ready();
  64. }
  65. }
  66. void CheckEntityViewsEngine(IEngine engine)
  67. {
  68. var baseType = engine.GetType().GetBaseType();
  69. while (baseType != _objectType)
  70. {
  71. if (baseType.IsGenericTypeEx())
  72. {
  73. var genericArguments = baseType.GetGenericArgumentsEx();
  74. AddEngine(engine as IHandleEntityViewEngineAbstracted, genericArguments, _entityEngines);
  75. return;
  76. }
  77. baseType = baseType.GetBaseType();
  78. }
  79. throw new ArgumentException("Not Supported Engine " + engine.ToString());
  80. }
  81. //The T parameter allows to pass datastructure sthat not necessarly are
  82. //defined with IEngine, but must be defined with IEngine implementations
  83. static void AddEngine<T>(T engine, Type[] entityViewTypes,
  84. Dictionary<Type, FasterList<T>> engines) where T:IEngine
  85. {
  86. for (int i = 0; i < entityViewTypes.Length; i++)
  87. {
  88. var type = entityViewTypes[i];
  89. AddEngine(engine, engines, type);
  90. }
  91. }
  92. static void AddEngine<T>(T engine, Dictionary<Type, FasterList<T>> engines, Type type) where T : IEngine
  93. {
  94. FasterList<T> list;
  95. if (engines.TryGetValue(type, out list) == false)
  96. {
  97. list = new FasterList<T>();
  98. engines.Add(type, list);
  99. }
  100. list.Add(engine);
  101. }
  102. readonly Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>> _entityEngines;
  103. readonly FasterList<IEngine> _otherEngines;
  104. readonly FasterList<IDisposable> _disposableEngines;
  105. static readonly Type _objectType = typeof(object);
  106. }
  107. }