After.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using System;
  2. using System.Diagnostics;
  3. using UnityEditor;
  4. namespace EnhancedHierarchy {
  5. /// <summary>Utility class for running async tasks within the main thread.</summary>
  6. public static class After {
  7. /// <summary>Wait for a condition to become true, then executes the callback.</summary>
  8. /// <param name="condition">Function that will be called every frame that returns whether to invoke the callback or not.</param>
  9. /// <param name="callback">The callback to be called when the condition becomes true.</param>
  10. /// <param name="timeoutMs">Maximum time to wait in milliseconds before cancelling the callback.</param>
  11. public static void Condition(Func<bool> condition, Action callback, double timeoutMs = 0d) {
  12. var update = new EditorApplication.CallbackFunction(() => { });
  13. var timeoutsAt = EditorApplication.timeSinceStartup + (timeoutMs / 1000d);
  14. var stack = new StackFrame(1, true);
  15. update = () => {
  16. if (timeoutMs > 0d && EditorApplication.timeSinceStartup >= timeoutsAt) {
  17. EditorApplication.update -= update;
  18. UnityEngine.Debug.LogErrorFormat("Condition timedout at {0}:{1}", stack.GetFileName(), stack.GetFileLineNumber());
  19. return;
  20. }
  21. if (condition()) {
  22. EditorApplication.update -= update;
  23. callback();
  24. }
  25. };
  26. EditorApplication.update += update;
  27. }
  28. /// <summary>Wait for the given amount of editor frames, then executes the callback.</summary>
  29. /// <param name="frames">The number of frames to wait for.</param>
  30. /// <param name="callback">The callback to be called after the specified frames.</param>
  31. public static void Frames(int frames, Action callback) {
  32. var f = 0;
  33. Condition(() => f++ >= frames, callback);
  34. }
  35. /// <summary>Wait for the given time, then executes the callback.</summary>
  36. /// <param name="milliseconds">How long to wait until calling the callback, in milliseconds.</param>
  37. /// <param name="callback">The callback to be called after the specified time.</param>
  38. public static void Milliseconds(double milliseconds, Action callback) {
  39. var end = EditorApplication.timeSinceStartup + (milliseconds / 1000f);
  40. Condition(() => EditorApplication.timeSinceStartup >= end, callback);
  41. }
  42. }
  43. }