public async Task RunCoroutineNonGeneric() { using var looper = new Cysharp.Threading.LogicLooper(60); var coroutine = default(LogicLooperCoroutine); var startFrame = 0L; await looper.RegisterActionAsync((in LogicLooperActionContext ctx) => { if (coroutine == null) { startFrame = ctx.CurrentFrame; coroutine = ctx.RunCoroutine(async ctx2 => { ctx2.CurrentFrame.Should().Be(startFrame); await ctx2.DelayFrame(60); ctx2.CurrentFrame.Should().Be(startFrame + 60); await ctx2.DelayNextFrame(); ctx2.CurrentFrame.Should().Be(startFrame + 61); await ctx2.Delay(TimeSpan.FromMilliseconds(16.66666)); ctx2.CurrentFrame.Should().Be(startFrame + 62); }); } return(!coroutine.IsCompleted); });
[InlineData(33.3333)] // 30fps public async Task TargetFrameTime(double targetFrameTimeMs) { using var looper = new Cysharp.Threading.LogicLooper(TimeSpan.FromMilliseconds(targetFrameTimeMs)); looper.ApproximatelyRunningActions.Should().Be(0); looper.TargetFrameRate.Should().Be(1000 / (double)targetFrameTimeMs); var beginTimestamp = DateTime.Now.Ticks; var lastTimestamp = beginTimestamp; var fps = 0d; var task = looper.RegisterActionAsync((in LogicLooperActionContext ctx) => { var now = DateTime.Now.Ticks; var elapsedFromBeginMilliseconds = (now - beginTimestamp) / TimeSpan.TicksPerMillisecond; var elapsedFromPreviousFrameMilliseconds = (now - lastTimestamp) / TimeSpan.TicksPerMillisecond; if (elapsedFromPreviousFrameMilliseconds == 0) { return(true); } fps = (fps + (1000 / elapsedFromPreviousFrameMilliseconds)) / 2d; lastTimestamp = now; return(elapsedFromBeginMilliseconds < 3000); // 3 seconds });