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.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;
}
}
}
}

4
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();

Loading…
Cancel
Save