IDispatcher.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using System;
  2. using System.Threading;
  3. using UnityEngine;
  4. using Queue = System.Collections.Generic.List<System.Action>;
  5. namespace Immersal.Samples.Util
  6. {
  7. public abstract class IDispatch
  8. {
  9. protected Thread targetThread;
  10. protected Queue pending, executing;
  11. protected readonly Camera.CameraCallback updateLoop;
  12. protected readonly object queueLock = new object();
  13. public virtual void Dispatch(Action action, bool repeating = false)
  14. {
  15. if (action == null) return;
  16. Action actionWrapper = action;
  17. if (repeating) actionWrapper = delegate()
  18. {
  19. action();
  20. lock (queueLock) pending.Add(actionWrapper);
  21. };
  22. if (Thread.CurrentThread.ManagedThreadId == targetThread.ManagedThreadId && !repeating) actionWrapper();
  23. else lock (queueLock) pending.Add(actionWrapper);
  24. }
  25. public virtual void Release()
  26. {
  27. Camera.onPostRender -= updateLoop;
  28. pending.Clear(); executing.Clear();
  29. pending = executing = null;
  30. }
  31. protected virtual void Update()
  32. {
  33. lock (queueLock) {
  34. executing.AddRange(pending);
  35. pending.Clear();
  36. }
  37. executing.ForEach(e => e());
  38. executing.Clear();
  39. }
  40. protected IDispatch()
  41. {
  42. updateLoop = cam => Update();
  43. pending = new Queue();
  44. executing = new Queue();
  45. }
  46. }
  47. }