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.

114 lines
5.1KB

  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.Extensions.Unity
  7. {
  8. /// <summary>
  9. /// This is a high level class to abstract the complexity of creating a Svelto ECS application that interacts
  10. /// with UECS. 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. The flow should be:
  14. /// Svelto Engines Run
  15. /// This Engine runs, which causeS:
  16. /// Jobs to be completed (it's a sync point)
  17. /// Synchronizations engines to be executed (Svelto to UECS)
  18. /// Submission of Entities to be executed
  19. /// Svelto Add/Remove callbacks to be called
  20. /// ISubmissionEngines to be executed
  21. /// UECS engines to executed
  22. /// Synchronizations engines to be executed (UECS To Svelto)
  23. /// </summary>
  24. [Sequenced(nameof(JobifiedSveltoEngines.SveltoOverUECS))]
  25. public class SveltoOverUECSEnginesGroup: IJobifiedEngine
  26. {
  27. public SveltoOverUECSEnginesGroup(EnginesRoot enginesRoot)
  28. {
  29. DBC.ECS.Check.Require(enginesRoot.scheduler is SimpleEntitiesSubmissionScheduler, "The Engines root must use a EntitiesSubmissionScheduler scheduler implementation");
  30. CreateUnityECSWorldForSvelto(enginesRoot.scheduler as SimpleEntitiesSubmissionScheduler, enginesRoot);
  31. }
  32. public World world { get; private set; }
  33. void CreateUnityECSWorldForSvelto(SimpleEntitiesSubmissionScheduler scheduler, EnginesRoot enginesRoot)
  34. {
  35. world = new World("Svelto<>UECS world");
  36. var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
  37. DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
  38. World.DefaultGameObjectInjectionWorld = world;
  39. //This is the UECS group that takes care of all the UECS systems that creates entities
  40. //it also submits Svelto entities
  41. _sveltoUecsEntitiesSubmissionGroup = new SveltoUECSEntitiesSubmissionGroup(scheduler, world);
  42. //This is the group that handles the UECS sync systems that copy the svelto entities values to UECS entities
  43. _syncSveltoToUecsGroup = new SyncSveltoToUECSGroup();
  44. enginesRoot.AddEngine(_syncSveltoToUecsGroup);
  45. _syncUecsToSveltoGroup = new SyncUECSToSveltoGroup();
  46. enginesRoot.AddEngine(_syncUecsToSveltoGroup);
  47. //This is the group that handles the UECS sync systems that copy the UECS entities values to svelto entities
  48. //enginesRoot.AddEngine(new SveltoUECSEntitiesSubmissionGroup(scheduler, world));
  49. enginesRoot.AddEngine(this);
  50. _enginesRoot = enginesRoot;
  51. }
  52. public JobHandle Execute(JobHandle inputDeps)
  53. {
  54. //this is a sync point, there won't be pending jobs after this
  55. _sveltoUecsEntitiesSubmissionGroup.SubmitEntities(inputDeps);
  56. //Mixed explicit job dependency and internal automatic ECS dependency system
  57. //Write in to UECS entities so the UECS dependencies react on the components touched
  58. var handle = _syncSveltoToUecsGroup.Execute(default);
  59. //As long as pure UECS systems do not use external containers (like native arrays and so) the Unity
  60. //automatic dependencies system will guarantee that there won't be race conditions
  61. world.Update();
  62. //this svelto group of UECS SystemBase systems
  63. return _syncUecsToSveltoGroup.Execute(handle);
  64. }
  65. public void AddUECSSubmissionEngine(SubmissionEngine spawnUnityEntityOnSveltoEntityEngine)
  66. {
  67. _sveltoUecsEntitiesSubmissionGroup.Add(spawnUnityEntityOnSveltoEntityEngine);
  68. _enginesRoot.AddEngine(spawnUnityEntityOnSveltoEntityEngine);
  69. }
  70. public void AddSveltoToUECSEngine(SyncSveltoToUECSEngine engine)
  71. {
  72. //it's a Svelto Engine/UECS SystemBase so it must be added in the UECS world AND svelto enginesRoot
  73. world.AddSystem(engine);
  74. _enginesRoot.AddEngine(engine);
  75. _syncSveltoToUecsGroup.Add(engine);
  76. }
  77. public void AddUECSToSveltoEngine(SyncUECSToSveltoEngine engine)
  78. {
  79. //it's a Svelto Engine/UECS SystemBase so it must be added in the UECS world AND svelto enginesRoot
  80. world.AddSystem(engine);
  81. _enginesRoot.AddEngine(engine);
  82. _syncUecsToSveltoGroup.Add(engine);
  83. }
  84. public void Dispose()
  85. {
  86. world.Dispose();
  87. }
  88. public string name => nameof(SveltoOverUECSEnginesGroup);
  89. SveltoUECSEntitiesSubmissionGroup _sveltoUecsEntitiesSubmissionGroup;
  90. SyncSveltoToUECSGroup _syncSveltoToUecsGroup;
  91. SyncUECSToSveltoGroup _syncUecsToSveltoGroup;
  92. EnginesRoot _enginesRoot;
  93. }
  94. }
  95. #endif