MotionTracker.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. namespace LitMotion
  5. {
  6. /// <summary>
  7. /// Provides functionality for tracking active motions.
  8. /// </summary>
  9. public static class MotionTracker
  10. {
  11. public static bool EnableTracking = false;
  12. public static bool EnableStackTrace = false;
  13. public static IReadOnlyList<TrackingState> Items => trackings;
  14. static readonly List<TrackingState> trackings = new(16);
  15. public static void AddTracking(MotionHandle motionHandle, IMotionScheduler scheduler, int skipFrames = 3)
  16. {
  17. var state = TrackingState.Create();
  18. (state.ValueType, state.OptionsType, state.AdapterType) = MotionStorageManager.GetMotionType(motionHandle);
  19. state.Scheduler = scheduler;
  20. state.CreationTime = DateTime.UtcNow;
  21. #if UNITY_EDITOR
  22. state.CreatedOnEditor = UnityEditor.EditorApplication.isPlaying;
  23. #endif
  24. if (EnableStackTrace) state.StackTrace = new StackTrace(skipFrames, true);
  25. ref var callbackData = ref MotionStorageManager.GetMotionCallbackDataRef(motionHandle);
  26. state.OriginalOnCompleteCallback = callbackData.OnCompleteAction;
  27. callbackData.OnCompleteAction = state.OnCompleteDelegate;
  28. state.OriginalOnCancelCallback = callbackData.OnCancelAction;
  29. callbackData.OnCancelAction = state.OnCancelDelegate;
  30. trackings.Add(state);
  31. }
  32. public static void Clear()
  33. {
  34. trackings.Clear();
  35. }
  36. public sealed class TrackingState
  37. {
  38. static readonly Stack<TrackingState> pool = new(16);
  39. TrackingState()
  40. {
  41. OnCompleteDelegate = OnComplete;
  42. OnCancelDelegate = OnCancel;
  43. }
  44. public static TrackingState Create()
  45. {
  46. if (!pool.TryPop(out var state))
  47. {
  48. state = new();
  49. }
  50. return state;
  51. }
  52. public Type ValueType;
  53. public Type OptionsType;
  54. public Type AdapterType;
  55. public IMotionScheduler Scheduler;
  56. public DateTime CreationTime;
  57. public StackTrace StackTrace;
  58. public bool CreatedOnEditor;
  59. public Action OriginalOnCompleteCallback;
  60. public Action OriginalOnCancelCallback;
  61. public readonly Action OnCompleteDelegate;
  62. public readonly Action OnCancelDelegate;
  63. void OnComplete()
  64. {
  65. try
  66. {
  67. OriginalOnCompleteCallback?.Invoke();
  68. }
  69. catch (Exception ex)
  70. {
  71. MotionDispatcher.GetUnhandledExceptionHandler()?.Invoke(ex);
  72. }
  73. Release();
  74. }
  75. void OnCancel()
  76. {
  77. try
  78. {
  79. OriginalOnCancelCallback?.Invoke();
  80. }
  81. catch (Exception ex)
  82. {
  83. MotionDispatcher.GetUnhandledExceptionHandler()?.Invoke(ex);
  84. }
  85. Release();
  86. }
  87. void Release()
  88. {
  89. trackings.Remove(this);
  90. ValueType = default;
  91. OptionsType = default;
  92. AdapterType = default;
  93. Scheduler = default;
  94. CreationTime = default;
  95. StackTrace = default;
  96. CreatedOnEditor = default;
  97. OriginalOnCompleteCallback = default;
  98. OriginalOnCancelCallback = default;
  99. pool.Push(this);
  100. }
  101. }
  102. }
  103. }