Browse Source

Pulse animation timer from render loop.

pull/1715/head
Steven Kirk 8 years ago
committed by Jeremy Koritzinsky
parent
commit
166f9f8cf0
  1. 35
      src/Avalonia.Animation/Timing.cs
  2. 4
      src/Avalonia.Visuals/Rendering/RenderLoop.cs

35
src/Avalonia.Animation/Timing.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Reactive;
using Avalonia.Threading; using Avalonia.Threading;
namespace Avalonia.Animation namespace Avalonia.Animation
@ -13,42 +14,38 @@ namespace Avalonia.Animation
/// </summary> /// </summary>
public static class Timing public static class Timing
{ {
/// <summary> static TimerObservable _timer = new TimerObservable();
/// 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);
/// <summary> /// <summary>
/// Initializes static members of the <see cref="Timing"/> class. /// Initializes static members of the <see cref="Timing"/> class.
/// </summary> /// </summary>
static Timing() static Timing()
{ {
var globalTimer = Observable.Interval(FrameTick, AvaloniaScheduler.Instance); AnimationsTimer = _timer
AnimationsTimer = globalTimer
.Select(_ => GetTickCount())
.Publish() .Publish()
.RefCount(); .RefCount();
} }
public static bool HasSubscriptions => _timer.HasSubscriptions;
internal static TimeSpan GetTickCount() => TimeSpan.FromMilliseconds(Environment.TickCount); internal static TimeSpan GetTickCount() => TimeSpan.FromMilliseconds(Environment.TickCount);
/// <summary> /// <summary>
/// Gets the animation timer. /// Gets the animation timer.
/// </summary> /// </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 internal static IObservable<TimeSpan> AnimationsTimer
{ {
get; 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;
}
} }
} }

4
src/Avalonia.Visuals/Rendering/RenderLoop.cs

@ -70,7 +70,7 @@ namespace Avalonia.Rendering
try try
{ {
var needsUpdate = false; var needsUpdate = Animation.Timing.HasSubscriptions;
foreach (var i in _items) foreach (var i in _items)
{ {
@ -85,6 +85,8 @@ namespace Avalonia.Rendering
{ {
await _dispatcher.InvokeAsync(() => await _dispatcher.InvokeAsync(() =>
{ {
Animation.Timing.Pulse(tickCount);
foreach (var i in _items) foreach (var i in _items)
{ {
i.Update(); i.Update();

Loading…
Cancel
Save