diff --git a/src/Avalonia.Animation/Clock.cs b/src/Avalonia.Animation/Clock.cs index e8616c9694..f61a4c7db1 100644 --- a/src/Avalonia.Animation/Clock.cs +++ b/src/Avalonia.Animation/Clock.cs @@ -6,81 +6,20 @@ using Avalonia.Reactive; namespace Avalonia.Animation { - public class Clock : IObservable + public class Clock : ClockBase { - public static Clock GlobalClock => AvaloniaLocator.Current.GetService(); - - private ClockObservable _observable; - - private IObservable _connectedObservable; + public static IClock GlobalClock => AvaloniaLocator.Current.GetService(); 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 observer) - { - return _connectedObservable.Subscribe(observer); - } - - private class ClockObservable : LightweightObservableBase - { - 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; - } } } diff --git a/src/Avalonia.Animation/ClockBase.cs b/src/Avalonia.Animation/ClockBase.cs new file mode 100644 index 0000000000..ea784269d9 --- /dev/null +++ b/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 _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 observer) + { + return _connectedObservable.Subscribe(observer); + } + + private class ClockObservable : LightweightObservableBase + { + 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; + } + } +} diff --git a/src/Avalonia.Animation/IClock.cs b/src/Avalonia.Animation/IClock.cs new file mode 100644 index 0000000000..58c997841d --- /dev/null +++ b/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 + { + bool HasSubscriptions { get; } + TimeSpan CurrentTime { get; } + PlayState PlayState { get; set; } + } +} diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 8f6544ccd8..8c03bac61a 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -340,7 +340,7 @@ namespace Avalonia var clock = new RenderLoopClock(); AvaloniaLocator.CurrentMutable - .Bind().ToConstant(clock) + .Bind().ToConstant(clock) .GetService().Add(clock); } } diff --git a/src/Avalonia.Visuals/Animation/RenderLoopClock.cs b/src/Avalonia.Visuals/Animation/RenderLoopClock.cs index d9ee269739..e59b3aac0d 100644 --- a/src/Avalonia.Visuals/Animation/RenderLoopClock.cs +++ b/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() {