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.

132 lines
5.1KB

  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. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  16. static EnginesRoot()
  17. {
  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. }
  25. #endif
  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(IEntitySubmissionScheduler 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. _transientEntitiesOperations = new FasterList<EntitySubmitOperation>();
  41. _groupEntityDB = new FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>();
  42. _groupsPerEntity = new Dictionary<Type, FasterDictionary<int, ITypeSafeDictionary>>();
  43. _groupedEntityToAdd = new DoubleBufferedEntitiesToAdd<FasterDictionary<int, Dictionary<Type, ITypeSafeDictionary>>>();
  44. _DB = new EntitiesDB(_groupEntityDB, _groupsPerEntity);
  45. _scheduler = entityViewScheduler;
  46. _scheduler.onTick = new WeakAction(SubmitEntityViews);
  47. }
  48. public void AddEngine(IEngine engine)
  49. {
  50. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  51. Profiler.EngineProfiler.AddEngine(engine);
  52. #endif
  53. var viewEngine = engine as IHandleEntityViewEngineAbstracted;
  54. if (viewEngine != null)
  55. CheckEntityViewsEngine(viewEngine);
  56. else
  57. _otherEngines.Add(engine);
  58. if (engine is IDisposable)
  59. _disposableEngines.Add(engine as IDisposable);
  60. var queryableEntityViewEngine = engine as IQueryingEntitiesEngine;
  61. if (queryableEntityViewEngine != null)
  62. {
  63. queryableEntityViewEngine.entitiesDB = _DB;
  64. queryableEntityViewEngine.Ready();
  65. }
  66. }
  67. void CheckEntityViewsEngine(IEngine engine)
  68. {
  69. var baseType = engine.GetType().GetBaseType();
  70. while (baseType != _objectType)
  71. {
  72. if (baseType.IsGenericTypeEx())
  73. {
  74. var genericArguments = baseType.GetGenericArgumentsEx();
  75. AddEngine(engine as IHandleEntityViewEngineAbstracted, genericArguments, _entityEngines);
  76. return;
  77. }
  78. baseType = baseType.GetBaseType();
  79. }
  80. throw new ArgumentException("Not Supported Engine " + engine.ToString());
  81. }
  82. //The T parameter allows to pass datastructure sthat not necessarly are
  83. //defined with IEngine, but must be defined with IEngine implementations
  84. static void AddEngine<T>(T engine, Type[] entityViewTypes,
  85. Dictionary<Type, FasterList<T>> engines) where T:IEngine
  86. {
  87. for (int i = 0; i < entityViewTypes.Length; i++)
  88. {
  89. var type = entityViewTypes[i];
  90. AddEngine(engine, engines, type);
  91. }
  92. }
  93. static void AddEngine<T>(T engine, Dictionary<Type, FasterList<T>> engines, Type type) where T : IEngine
  94. {
  95. FasterList<T> list;
  96. if (engines.TryGetValue(type, out list) == false)
  97. {
  98. list = new FasterList<T>();
  99. engines.Add(type, list);
  100. }
  101. list.Add(engine);
  102. }
  103. readonly Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>> _entityEngines;
  104. readonly FasterList<IEngine> _otherEngines;
  105. readonly FasterList<IDisposable> _disposableEngines;
  106. static readonly Type _objectType = typeof(object);
  107. }
  108. }