committed by
GitHub
210 changed files with 1332 additions and 855 deletions
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Animation.Animators; |
||||
|
|
||||
|
namespace Avalonia.Animation; |
||||
|
|
||||
|
public abstract class CustomAnimatorBase |
||||
|
{ |
||||
|
internal abstract IAnimator CreateWrapper(); |
||||
|
internal abstract Type WrapperType { get; } |
||||
|
} |
||||
|
|
||||
|
public abstract class CustomAnimatorBase<T> : CustomAnimatorBase |
||||
|
{ |
||||
|
public abstract T Interpolate(double progress, T oldValue, T newValue); |
||||
|
|
||||
|
internal override Type WrapperType => typeof(AnimatorWrapper); |
||||
|
internal override IAnimator CreateWrapper() => new AnimatorWrapper(this); |
||||
|
|
||||
|
internal class AnimatorWrapper : Animator<T> |
||||
|
{ |
||||
|
private readonly CustomAnimatorBase<T> _parent; |
||||
|
|
||||
|
public AnimatorWrapper(CustomAnimatorBase<T> parent) |
||||
|
{ |
||||
|
_parent = parent; |
||||
|
} |
||||
|
|
||||
|
public override T Interpolate(double progress, T oldValue, T newValue) => _parent.Interpolate(progress, oldValue, newValue); |
||||
|
} |
||||
|
} |
||||
@ -1,26 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Text; |
|
||||
using Avalonia.Rendering; |
|
||||
|
|
||||
namespace Avalonia.Animation |
|
||||
{ |
|
||||
public class RenderLoopClock : ClockBase, IRenderLoopTask, IGlobalClock |
|
||||
{ |
|
||||
protected override void Stop() |
|
||||
{ |
|
||||
AvaloniaLocator.Current.GetRequiredService<IRenderLoop>().Remove(this); |
|
||||
} |
|
||||
|
|
||||
bool IRenderLoopTask.NeedsUpdate => HasSubscriptions; |
|
||||
|
|
||||
void IRenderLoopTask.Render() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
void IRenderLoopTask.Update(TimeSpan time) |
|
||||
{ |
|
||||
Pulse(time); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,53 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using Avalonia.Animation; |
||||
|
using Avalonia.Reactive; |
||||
|
using Avalonia.Threading; |
||||
|
|
||||
|
namespace Avalonia.Media; |
||||
|
|
||||
|
internal partial class MediaContext |
||||
|
{ |
||||
|
private readonly MediaContextClock _clock; |
||||
|
public IGlobalClock Clock => _clock; |
||||
|
private readonly Stopwatch _time = Stopwatch.StartNew(); |
||||
|
|
||||
|
class MediaContextClock : IGlobalClock |
||||
|
{ |
||||
|
private readonly MediaContext _parent; |
||||
|
private List<IObserver<TimeSpan>> _observers = new(); |
||||
|
public bool HasNewSubscriptions { get; set; } |
||||
|
public bool HasSubscriptions => _observers.Count > 0; |
||||
|
|
||||
|
public MediaContextClock(MediaContext parent) |
||||
|
{ |
||||
|
_parent = parent; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Subscribe(IObserver<TimeSpan> observer) |
||||
|
{ |
||||
|
_parent.ScheduleRender(false); |
||||
|
Dispatcher.UIThread.VerifyAccess(); |
||||
|
HasNewSubscriptions = true; |
||||
|
_observers.Add(observer); |
||||
|
return Disposable.Create(() => |
||||
|
{ |
||||
|
Dispatcher.UIThread.VerifyAccess(); |
||||
|
_observers.Remove(observer); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public void Pulse(TimeSpan now) |
||||
|
{ |
||||
|
foreach (var observer in _observers.ToArray()) |
||||
|
observer.OnNext(now); |
||||
|
} |
||||
|
|
||||
|
public PlayState PlayState |
||||
|
{ |
||||
|
get => PlayState.Run; |
||||
|
set => throw new InvalidOperationException(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue