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.

151 lines
6.3KB

  1. #if UNITY_ECS
  2. using Svelto.Common;
  3. using Svelto.ECS.Schedulers;
  4. using Unity.Entities;
  5. using Unity.Jobs;
  6. namespace Svelto.ECS.SveltoOnDOTS
  7. {
  8. /// <summary>
  9. /// This is a high level class to abstract the complexity of creating a Svelto ECS application that interacts
  10. /// with DOTS ECS.
  11. /// This is a JobifiedEngine and as such it expect to be ticked. Normally it must be executed in a
  12. /// SortedEnginesGroup as step that happens after the Svelto jobified engines run.
  13. ///
  14. /// The flow should be:
  15. /// Svelto (GameLogic) Engines Run first
  16. /// Then this Engine runs, which causes:
  17. /// Jobs to be completed (it's a sync point)
  18. /// Synchronizations engines to be executed (Svelto to DOTS ECS)
  19. /// Submission of Entities to be executed
  20. /// Svelto Add/Remove callbacks to be called
  21. /// ISveltoOnDOTSStructuralEngine to be executed
  22. /// DOTS ECS engines to be executed
  23. /// Synchronizations engines to be executed (DOTS ECS To Svelto)
  24. /// </summary>
  25. [Sequenced(nameof(JobifiedSveltoEngines.SveltoOnDOTS))]
  26. public class SveltoOnDOTSEnginesGroup: IJobifiedEngine
  27. {
  28. public SveltoOnDOTSEnginesGroup(EnginesRoot enginesRoot)
  29. {
  30. DBC.ECS.Check.Require(
  31. enginesRoot.scheduler is SimpleEntitiesSubmissionScheduler
  32. , "The Engines root must use a EntitiesSubmissionScheduler scheduler implementation");
  33. CreateUnityECSWorldForSvelto(enginesRoot.scheduler as SimpleEntitiesSubmissionScheduler, enginesRoot);
  34. }
  35. /// <summary>
  36. /// for the user to add pure DOTS ECS SystemBase/ISystem systems to the DOTS ECS world
  37. /// </summary>
  38. public World world { get; private set; }
  39. /// <summary>
  40. /// for the user to be able to explicitly submit entities. When SveltoOnDOTS is used, you must use this way, you cannot
  41. /// submit entities directly from the EnginesRoot submission scheduler
  42. /// </summary>
  43. public ISveltoOnDOTSSubmission submitter => _sveltoDotsEntitiesSubmissionGroup;
  44. public JobHandle Execute(JobHandle inputDeps)
  45. {
  46. //this is a sync point, there won't be pending jobs after this
  47. _sveltoDotsEntitiesSubmissionGroup.SubmitEntities(inputDeps);
  48. //Mixed explicit job dependency and internal automatic ECS dependency system
  49. //Write in to DOTS ECS entities so the DOTS ECS dependencies react on the components touched
  50. var handle = _syncSveltoToDotsGroup.Execute(default);
  51. //As long as pure DOTS ECS systems do not use external containers (like native arrays and so) the Unity
  52. //automatic dependencies system will guarantee that there won't be race conditions
  53. world.Update();
  54. //this svelto group of DOTS ECS SystemBase systems
  55. return _syncDotsToSveltoGroup.Execute(handle);
  56. }
  57. public string name => nameof(SveltoOnDOTSEnginesGroup);
  58. public void AddSveltoToDOTSSyncEngine(SyncSveltoToDOTSEngine engine)
  59. {
  60. //it's a Svelto Engine/DOTS ECS SystemBase so it must be added in the DOTS ECS world AND svelto enginesRoot
  61. #if UNITY_ECS_100
  62. world.AddSystemManaged(engine);
  63. #else
  64. world.AddSystem(engine);
  65. #endif
  66. _enginesRoot.AddEngine(engine);
  67. _syncSveltoToDotsGroup.Add(engine);
  68. }
  69. public void AddDOTSToSveltoSyncEngine(SyncDOTSToSveltoEngine engine)
  70. {
  71. //it's a Svelto Engine/DOTS ECS SystemBase so it must be added in the DOTS ECS world AND svelto enginesRoot
  72. #if UNITY_ECS_100
  73. world.AddSystemManaged(engine);
  74. #else
  75. world.AddSystem(engine);
  76. #endif
  77. _enginesRoot.AddEngine(engine);
  78. _syncDotsToSveltoGroup.Add(engine);
  79. }
  80. public void AddSveltoOnDOTSSubmissionEngine(ISveltoOnDOTSStructuralEngine submissionEngine)
  81. {
  82. _sveltoDotsEntitiesSubmissionGroup.Add(submissionEngine);
  83. if (submissionEngine is IEngine enginesRootEngine)
  84. _enginesRoot.AddEngine(enginesRootEngine);
  85. }
  86. public void Dispose()
  87. {
  88. world.Dispose();
  89. }
  90. void CreateUnityECSWorldForSvelto(SimpleEntitiesSubmissionScheduler scheduler, EnginesRoot enginesRoot)
  91. {
  92. world = new World("Svelto<>DOTS world");
  93. var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
  94. DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
  95. World.DefaultGameObjectInjectionWorld = world;
  96. //This is the DOTS ECS group that takes care of all the DOTS ECS systems that creates entities
  97. //it also submits Svelto entities through the scheduler
  98. var defaultSveltoOnDotsHandleLifeTimeEngine = new SveltoOnDOTSHandleLifeTimeEngine<DOTSEntityComponent>();
  99. _sveltoDotsEntitiesSubmissionGroup = new SveltoOnDOTSEntitiesSubmissionGroup(scheduler);
  100. enginesRoot.AddEngine(defaultSveltoOnDotsHandleLifeTimeEngine);
  101. _sveltoDotsEntitiesSubmissionGroup.Add(defaultSveltoOnDotsHandleLifeTimeEngine);
  102. enginesRoot.AddEngine(_sveltoDotsEntitiesSubmissionGroup);
  103. #if UNITY_ECS_100
  104. world.AddSystemManaged(_sveltoDotsEntitiesSubmissionGroup);
  105. #else
  106. world.AddSystem(_sveltoDotsEntitiesSubmissionGroup);
  107. #endif
  108. //This is the group that handles the DOTS ECS sync systems that copy the svelto entities values to DOTS ECS entities
  109. _syncSveltoToDotsGroup = new SyncSveltoToDOTSGroup();
  110. enginesRoot.AddEngine(_syncSveltoToDotsGroup);
  111. //This is the group that handles the DOTS ECS sync systems that copy the DOTS ECS entities values to svelto entities
  112. _syncDotsToSveltoGroup = new SyncDOTSToSveltoGroup();
  113. enginesRoot.AddEngine(_syncDotsToSveltoGroup);
  114. enginesRoot.AddEngine(this);
  115. _enginesRoot = enginesRoot;
  116. }
  117. EnginesRoot _enginesRoot;
  118. SveltoOnDOTSEntitiesSubmissionGroup _sveltoDotsEntitiesSubmissionGroup;
  119. SyncSveltoToDOTSGroup _syncSveltoToDotsGroup;
  120. SyncDOTSToSveltoGroup _syncDotsToSveltoGroup;
  121. }
  122. }
  123. #endif