From 166f9f8cf01d27dd8a9afa040497c357f0e5eb6b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 28 Jun 2018 11:02:50 +0200 Subject: [PATCH] Pulse animation timer from render loop. --- src/Avalonia.Animation/Timing.cs | 35 +++++++++----------- src/Avalonia.Visuals/Rendering/RenderLoop.cs | 4 ++- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/Avalonia.Animation/Timing.cs b/src/Avalonia.Animation/Timing.cs index 6367425911..d6a353fb34 100644 --- a/src/Avalonia.Animation/Timing.cs +++ b/src/Avalonia.Animation/Timing.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Reactive.Linq; +using Avalonia.Reactive; using Avalonia.Threading; namespace Avalonia.Animation @@ -13,42 +14,38 @@ namespace Avalonia.Animation /// public static class Timing { - /// - /// The number of frames per second. - /// - public const int FramesPerSecond = 60; - - /// - /// The time span of each frame. - /// - internal static readonly TimeSpan FrameTick = TimeSpan.FromSeconds(1.0 / FramesPerSecond); + static TimerObservable _timer = new TimerObservable(); /// /// Initializes static members of the class. /// static Timing() { - var globalTimer = Observable.Interval(FrameTick, AvaloniaScheduler.Instance); - - AnimationsTimer = globalTimer - .Select(_ => GetTickCount()) + AnimationsTimer = _timer .Publish() .RefCount(); } + public static bool HasSubscriptions => _timer.HasSubscriptions; + internal static TimeSpan GetTickCount() => TimeSpan.FromMilliseconds(Environment.TickCount); /// /// Gets the animation timer. /// - /// - /// The animation timer triggers usually at 60 times per second or as - /// defined in . - /// The parameter passed to a subsciber is the current playstate of the animation. - /// internal static IObservable AnimationsTimer { get; } + + public static void Pulse(long tickCount) => _timer.Pulse(tickCount); + + private class TimerObservable : LightweightObservableBase + { + public bool HasSubscriptions { get; private set; } + public void Pulse(long tickCount) => PublishNext(TimeSpan.FromMilliseconds(tickCount)); + protected override void Initialize() => HasSubscriptions = true; + protected override void Deinitialize() => HasSubscriptions = false; + } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Visuals/Rendering/RenderLoop.cs b/src/Avalonia.Visuals/Rendering/RenderLoop.cs index bdcfdcba8e..5cac6993ff 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLoop.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLoop.cs @@ -70,7 +70,7 @@ namespace Avalonia.Rendering try { - var needsUpdate = false; + var needsUpdate = Animation.Timing.HasSubscriptions; foreach (var i in _items) { @@ -85,6 +85,8 @@ namespace Avalonia.Rendering { await _dispatcher.InvokeAsync(() => { + Animation.Timing.Pulse(tickCount); + foreach (var i in _items) { i.Update();