diff --git a/src/LogicLooper/LogicLooper.cs b/src/LogicLooper/LogicLooper.cs index 8935049..bff2082 100644 --- a/src/LogicLooper/LogicLooper.cs +++ b/src/LogicLooper/LogicLooper.cs @@ -22,12 +22,18 @@ public sealed class LogicLooper : ILogicLooper, IDisposable private static int _looperSequence = 0; [ThreadStatic] - private static LogicLooper? _threadLocalLooper = default; + private static ILogicLooper? _threadLocalLooper = default; /// /// Gets a looper of the current thread. /// - public static LogicLooper? Current => _threadLocalLooper; + public static ILogicLooper? Current + { + get => _threadLocalLooper; + + // NOTE: Setter to set from ManualLogicLooper for testing purposes + internal set => _threadLocalLooper = value; + } private readonly int _looperId; private readonly Thread _runLoopThread; @@ -235,8 +241,9 @@ private Task RegisterActionAsyncCore(LooperAction action) private static void StartRunLoop(object? state) { - _threadLocalLooper = ((LogicLooper)state!); - _threadLocalLooper.RunLoop(); + var logicLooper = ((LogicLooper)state!); + _threadLocalLooper = logicLooper; + logicLooper.RunLoop(); } private void RunLoop() diff --git a/src/LogicLooper/ManualLogicLooper.cs b/src/LogicLooper/ManualLogicLooper.cs index 2c46df8..e758868 100644 --- a/src/LogicLooper/ManualLogicLooper.cs +++ b/src/LogicLooper/ManualLogicLooper.cs @@ -62,20 +62,29 @@ public bool Tick() var completed = new List(); lock (_actions) { - foreach (var action in _actions.ToArray()) + var origCurrentLogicLooper = LogicLooper.Current; + try { - if (!InvokeAction(ctx, action)) + LogicLooper.Current = this; + foreach (var action in _actions.ToArray()) { - completed.Add(action); + if (!InvokeAction(ctx, action)) + { + completed.Add(action); + } + } + + foreach (var completedAction in completed) + { + _actions.Remove(completedAction); } - } - foreach (var completedAction in completed) + return _actions.Count != 0; + } + finally { - _actions.Remove(completedAction); + LogicLooper.Current = origCurrentLogicLooper; } - - return _actions.Count != 0; } } diff --git a/test/LogicLooper.Test/ManualLogicLooperTest.cs b/test/LogicLooper.Test/ManualLogicLooperTest.cs index 38c0958..6d32e40 100644 --- a/test/LogicLooper.Test/ManualLogicLooperTest.cs +++ b/test/LogicLooper.Test/ManualLogicLooperTest.cs @@ -175,4 +175,24 @@ public void RegisterActionAsync_State() looper.ApproximatelyRunningActions.Should().Be(0); t1.IsCompletedSuccessfully.Should().BeTrue(); } + + [Fact] + public void LogicLooper_Current() + { + Cysharp.Threading.LogicLooper.Current.Should().BeNull(); + + var looper = new ManualLogicLooper(60.0); + looper.TargetFrameRate.Should().Be(60.0); + + var currentLogicLooperInAction = default(ILogicLooper); + looper.RegisterActionAsync((in LogicLooperActionContext ctx) => + { + currentLogicLooperInAction = Cysharp.Threading.LogicLooper.Current; + return false; + }); + looper.Tick(); + + currentLogicLooperInAction.Should().Be(looper); + Cysharp.Threading.LogicLooper.Current.Should().BeNull(); + } }