CallbacksHolder.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace UnityEditor.TestTools.TestRunner.Api
  5. {
  6. internal class CallbacksHolder : ScriptableSingleton<CallbacksHolder>, ICallbacksHolder
  7. {
  8. private List<CallbackWithPriority> m_Callbacks = new List<CallbackWithPriority>();
  9. public void Add(ICallbacks callback, int priority)
  10. {
  11. m_Callbacks.Add(new CallbackWithPriority(callback, priority));
  12. }
  13. public void Remove(ICallbacks callback)
  14. {
  15. m_Callbacks.RemoveAll(callbackWithPriority => callbackWithPriority.Callback == callback);
  16. }
  17. public ICallbacks[] GetAll()
  18. {
  19. return m_Callbacks.OrderByDescending(callback => callback.Priority).Select(callback => callback.Callback).ToArray();
  20. }
  21. public void Clear()
  22. {
  23. m_Callbacks.Clear();
  24. }
  25. private struct CallbackWithPriority
  26. {
  27. public ICallbacks Callback;
  28. public int Priority;
  29. public CallbackWithPriority(ICallbacks callback, int priority)
  30. {
  31. Callback = callback;
  32. Priority = priority;
  33. }
  34. }
  35. // Sometimes - such as when we want to test the test framework itself - it's necessary to launch a test run from
  36. // inside a test. Because callbacks are registered globally, this can cause a lot of confusion (e.g. the in-test
  37. // run will emit UTP messages, utterly confusing UTR). In such circumstances the safest thing to do is to
  38. // temporarily suppress all registered callbacks for the duration of the in-test run. This method can be called
  39. // to set up a using() block which will suppress the callbacks for the scope.
  40. public IDisposable TemporarilySuppressCallbacks()
  41. {
  42. return new Suppressor(this);
  43. }
  44. private sealed class Suppressor : IDisposable
  45. {
  46. private readonly CallbacksHolder _instance;
  47. private readonly List<CallbackWithPriority> _suppressed;
  48. public Suppressor(CallbacksHolder instance)
  49. {
  50. _instance = instance;
  51. _suppressed = new List<CallbackWithPriority>(instance.m_Callbacks);
  52. instance.m_Callbacks.Clear();
  53. }
  54. public void Dispose()
  55. {
  56. _instance.m_Callbacks.AddRange(_suppressed);
  57. }
  58. }
  59. }
  60. }