Browse Source

Refactor clock types.

pull/1715/head
Jeremy Koritzinsky 8 years ago
parent
commit
0c611b981d
  1. 71
      src/Avalonia.Animation/Clock.cs
  2. 75
      src/Avalonia.Animation/ClockBase.cs
  3. 13
      src/Avalonia.Animation/IClock.cs
  4. 2
      src/Avalonia.Controls/Application.cs
  5. 2
      src/Avalonia.Visuals/Animation/RenderLoopClock.cs

71
src/Avalonia.Animation/Clock.cs

@ -6,81 +6,20 @@ using Avalonia.Reactive;
namespace Avalonia.Animation
{
public class Clock : IObservable<TimeSpan>
public class Clock : ClockBase
{
public static Clock GlobalClock => AvaloniaLocator.Current.GetService<Clock>();
private ClockObservable _observable;
private IObservable<TimeSpan> _connectedObservable;
public static IClock GlobalClock => AvaloniaLocator.Current.GetService<IClock>();
private IDisposable _parentSubscription;
private TimeSpan? _previousTime;
private TimeSpan _internalTime;
protected Clock()
{
_observable = new ClockObservable();
_connectedObservable = _observable.Publish().RefCount();
}
public Clock(Clock parent)
:this()
public Clock(IClock parent)
{
_parentSubscription = parent.Subscribe(Pulse);
}
public bool HasSubscriptions => _observable.HasSubscriptions;
public TimeSpan CurrentTime { get; private set; }
public PlayState PlayState { get; set; }
protected void Pulse(TimeSpan systemTime)
{
if (!_previousTime.HasValue)
{
_previousTime = systemTime;
_internalTime = TimeSpan.Zero;
}
else
{
if (PlayState == PlayState.Pause)
{
_previousTime = systemTime;
return;
}
var delta = systemTime - _previousTime;
_internalTime += delta.Value;
_previousTime = systemTime;
}
_observable.Pulse(_internalTime);
CurrentTime = _internalTime;
if (PlayState == PlayState.Stop)
{
Stop();
}
}
protected virtual void Stop()
protected override void Stop()
{
_parentSubscription?.Dispose();
}
public IDisposable Subscribe(IObserver<TimeSpan> observer)
{
return _connectedObservable.Subscribe(observer);
}
private class ClockObservable : LightweightObservableBase<TimeSpan>
{
public bool HasSubscriptions { get; private set; }
public void Pulse(TimeSpan time) => PublishNext(time);
protected override void Initialize() => HasSubscriptions = true;
protected override void Deinitialize() => HasSubscriptions = false;
}
}
}

75
src/Avalonia.Animation/ClockBase.cs

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Text;
using Avalonia.Reactive;
namespace Avalonia.Animation
{
public class ClockBase : IClock
{
private ClockObservable _observable;
private IObservable<TimeSpan> _connectedObservable;
private TimeSpan? _previousTime;
private TimeSpan _internalTime;
protected ClockBase()
{
_observable = new ClockObservable();
_connectedObservable = _observable.Publish().RefCount();
}
public bool HasSubscriptions => _observable.HasSubscriptions;
public TimeSpan CurrentTime { get; private set; }
public PlayState PlayState { get; set; }
protected void Pulse(TimeSpan systemTime)
{
if (!_previousTime.HasValue)
{
_previousTime = systemTime;
_internalTime = TimeSpan.Zero;
}
else
{
if (PlayState == PlayState.Pause)
{
_previousTime = systemTime;
return;
}
var delta = systemTime - _previousTime;
_internalTime += delta.Value;
_previousTime = systemTime;
}
_observable.Pulse(_internalTime);
CurrentTime = _internalTime;
if (PlayState == PlayState.Stop)
{
Stop();
}
}
protected virtual void Stop()
{
}
public IDisposable Subscribe(IObserver<TimeSpan> observer)
{
return _connectedObservable.Subscribe(observer);
}
private class ClockObservable : LightweightObservableBase<TimeSpan>
{
public bool HasSubscriptions { get; private set; }
public void Pulse(TimeSpan time) => PublishNext(time);
protected override void Initialize() => HasSubscriptions = true;
protected override void Deinitialize() => HasSubscriptions = false;
}
}
}

13
src/Avalonia.Animation/IClock.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Avalonia.Animation
{
public interface IClock : IObservable<TimeSpan>
{
bool HasSubscriptions { get; }
TimeSpan CurrentTime { get; }
PlayState PlayState { get; set; }
}
}

2
src/Avalonia.Controls/Application.cs

@ -340,7 +340,7 @@ namespace Avalonia
var clock = new RenderLoopClock();
AvaloniaLocator.CurrentMutable
.Bind<Clock>().ToConstant(clock)
.Bind<IClock>().ToConstant(clock)
.GetService<IRenderLoop>().Add(clock);
}
}

2
src/Avalonia.Visuals/Animation/RenderLoopClock.cs

@ -5,7 +5,7 @@ using Avalonia.Rendering;
namespace Avalonia.Animation
{
public class RenderLoopClock : Clock, IRenderLoopTask
public class RenderLoopClock : ClockBase, IRenderLoopTask
{
protected override void Stop()
{

Loading…
Cancel
Save