Kaynağa Gözat

Pulse animation timer from render loop.

Steven Kirk 7 yıl önce
ebeveyn
işleme
166f9f8cf0

+ 16 - 19
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
     /// </summary>
     public static class Timing
     {
-        /// <summary>
-        /// The number of frames per second.
-        /// </summary>
-        public const int FramesPerSecond = 60;
-
-        /// <summary>
-        /// The time span of each frame.
-        /// </summary>
-        internal static readonly TimeSpan FrameTick = TimeSpan.FromSeconds(1.0 / FramesPerSecond);
+        static TimerObservable _timer = new TimerObservable();
 
         /// <summary>
         /// Initializes static members of the <see cref="Timing"/> class.
         /// </summary>
         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);
 
         /// <summary>
         /// Gets the animation timer.
         /// </summary>
-        /// <remarks>
-        /// The animation timer triggers usually at 60 times per second or as
-        /// defined in <see cref="FramesPerSecond"/>.
-        /// The parameter passed to a subsciber is the current playstate of the animation.
-        /// </remarks>
         internal static IObservable<TimeSpan> AnimationsTimer
         {
             get;
         }
+
+        public static void Pulse(long tickCount) => _timer.Pulse(tickCount);
+
+        private class TimerObservable : LightweightObservableBase<TimeSpan>
+        {
+            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;
+        }
     }
-}
+}

+ 3 - 1
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();