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.

122 lines
5.4KB

  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. However this is designed to make it work almost out of the box, but it should be eventually
  11. /// substituted by project customized code.
  12. /// This is a JobifiedEngine and as such it expect to be ticked. Normally it must be executed in a
  13. /// SortedEnginesGroup as step that happens after the Svelto jobified engines run.
  14. ///
  15. /// The flow should be:
  16. /// Svelto (GameLogic) Engines Run first
  17. /// Then this Engine runs, which causes:
  18. /// Jobs to be completed (it's a sync point)
  19. /// Synchronizations engines to be executed (Svelto to DOTS ECS)
  20. /// Submission of Entities to be executed
  21. /// Svelto Add/Remove callbacks to be called
  22. /// ISubmissionEngines to be executed
  23. /// DOTS ECS engines to executed
  24. /// Synchronizations engines to be executed (DOTS ECS To Svelto)
  25. /// </summary>
  26. [Sequenced(nameof(JobifiedSveltoEngines.SveltoOnDOTS))]
  27. public class SveltoOnDOTSEnginesGroup : IJobifiedEngine
  28. {
  29. public SveltoOnDOTSEnginesGroup(EnginesRoot enginesRoot)
  30. {
  31. DBC.ECS.Check.Require(enginesRoot.scheduler is SimpleEntitiesSubmissionScheduler
  32. , "The Engines root must use a EntitiesSubmissionScheduler scheduler implementation");
  33. CreateUnityECSWorldForSvelto(enginesRoot.scheduler as SimpleEntitiesSubmissionScheduler, enginesRoot);
  34. }
  35. public World world { get; private set; }
  36. public JobHandle Execute(JobHandle inputDeps)
  37. {
  38. //this is a sync point, there won't be pending jobs after this
  39. _sveltoDotsEntitiesSubmissionGroup.SubmitEntities(inputDeps);
  40. //Mixed explicit job dependency and internal automatic ECS dependency system
  41. //Write in to DOTS ECS entities so the DOTS ECS dependencies react on the components touched
  42. var handle = _syncSveltoToDotsGroup.Execute(default);
  43. //As long as pure DOTS ECS systems do not use external containers (like native arrays and so) the Unity
  44. //automatic dependencies system will guarantee that there won't be race conditions
  45. world.Update();
  46. //this svelto group of DOTS ECS SystemBase systems
  47. return _syncDotsToSveltoGroup.Execute(handle);
  48. }
  49. public string name => nameof(SveltoOnDOTSEnginesGroup);
  50. public void AddSveltoToDOTSEngine(SyncSveltoToDOTSEngine engine)
  51. {
  52. //it's a Svelto Engine/DOTS ECS SystemBase so it must be added in the DOTS ECS world AND svelto enginesRoot
  53. world.AddSystem(engine);
  54. _enginesRoot.AddEngine(engine);
  55. _syncSveltoToDotsGroup.Add(engine);
  56. }
  57. public void AddDOTSToSveltoEngine(SyncDOTSToSveltoEngine engine)
  58. {
  59. //it's a Svelto Engine/DOTS ECS SystemBase so it must be added in the DOTS ECS world AND svelto enginesRoot
  60. world.AddSystem(engine);
  61. _enginesRoot.AddEngine(engine);
  62. _syncDotsToSveltoGroup.Add(engine);
  63. }
  64. public void AddDOTSSubmissionEngine(SveltoOnDOTSHandleCreationEngine submissionEngine)
  65. {
  66. _sveltoDotsEntitiesSubmissionGroup.Add(submissionEngine);
  67. if (submissionEngine is IEngine enginesRootEngine)
  68. _enginesRoot.AddEngine(enginesRootEngine);
  69. }
  70. public void Dispose()
  71. {
  72. world.Dispose();
  73. }
  74. void CreateUnityECSWorldForSvelto(SimpleEntitiesSubmissionScheduler scheduler, EnginesRoot enginesRoot)
  75. {
  76. world = new World("Svelto<>DOTS world");
  77. var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
  78. DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
  79. World.DefaultGameObjectInjectionWorld = world;
  80. //This is the DOTS ECS group that takes care of all the DOTS ECS systems that creates entities
  81. //it also submits Svelto entities
  82. _sveltoDotsEntitiesSubmissionGroup = new SveltoOnDOTSEntitiesSubmissionGroup(scheduler, enginesRoot);
  83. //This is the group that handles the DOTS ECS sync systems that copy the svelto entities values to DOTS ECS entities
  84. enginesRoot.AddEngine(_sveltoDotsEntitiesSubmissionGroup);
  85. world.AddSystem(_sveltoDotsEntitiesSubmissionGroup);
  86. _syncSveltoToDotsGroup = new SyncSveltoToDOTSGroup();
  87. enginesRoot.AddEngine(_syncSveltoToDotsGroup);
  88. _syncDotsToSveltoGroup = new SyncDOTSToSveltoGroup();
  89. enginesRoot.AddEngine(_syncDotsToSveltoGroup);
  90. //This is the group that handles the DOTS ECS sync systems that copy the DOTS ECS entities values to svelto entities
  91. //enginesRoot.AddEngine(new SveltoDOTS ECSEntitiesSubmissionGroup(scheduler, world));
  92. enginesRoot.AddEngine(this);
  93. _enginesRoot = enginesRoot;
  94. }
  95. EnginesRoot _enginesRoot;
  96. SveltoOnDOTSEntitiesSubmissionGroup _sveltoDotsEntitiesSubmissionGroup;
  97. SyncSveltoToDOTSGroup _syncSveltoToDotsGroup;
  98. SyncDOTSToSveltoGroup _syncDotsToSveltoGroup;
  99. }
  100. }
  101. #endif