PromiseManager.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // Copyright (c) 2025 TerraByte Inc.
  2. //
  3. // A static manager that hooks into the Unity Editor's update loop to process
  4. // promises, ensuring their callbacks are executed on the main thread.
  5. using UnityEditor;
  6. using UnityEngine.Scripting;
  7. using System.Collections.Generic;
  8. namespace Terra.Arbitrator.Promises
  9. {
  10. [Preserve]
  11. [InitializeOnLoad] // Ensures the static constructor is called when the editor loads.
  12. public static class PromiseManager
  13. {
  14. private static readonly List<ITrackablePromise> PendingPromises = new();
  15. static PromiseManager()
  16. {
  17. EditorApplication.update -= Update; // Ensure we don't get duplicate subscriptions on recompile
  18. EditorApplication.update += Update;
  19. }
  20. private static void Update()
  21. {
  22. // Lock to prevent modification while iterating, in case a callback adds another promise.
  23. lock (PendingPromises)
  24. {
  25. // Iterate backwards so we can safely remove items.
  26. for (var i = PendingPromises.Count - 1; i >= 0; i--)
  27. {
  28. // The Tick() method on the promise will return true when it's finished.
  29. // We use dynamic here to call Tick() without knowing the generic type of the promise.
  30. if (PendingPromises[i].Tick())
  31. {
  32. PendingPromises.RemoveAt(i);
  33. }
  34. }
  35. }
  36. }
  37. /// <summary>
  38. /// Registers a new promise to be ticked by the manager.
  39. /// </summary>
  40. public static void Track(ITrackablePromise promise)
  41. {
  42. lock (PendingPromises)
  43. {
  44. PendingPromises.Add(promise);
  45. }
  46. }
  47. }
  48. }