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.

124 lines
4.6KB

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