Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slim renderer spike #66

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions Maui.Core/Animation/AnimatableKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;

namespace System.Maui
{
internal class AnimatableKey
{
public AnimatableKey(IAnimatable animatable, string handle)
{
if (animatable == null)
{
throw new ArgumentNullException(nameof(animatable));
}

if (string.IsNullOrEmpty(handle))
{
throw new ArgumentException("Argument is null or empty", nameof(handle));
}

Animatable = new WeakReference<IAnimatable>(animatable);
Handle = handle;
}

public WeakReference<IAnimatable> Animatable { get; }

public string Handle { get; }

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != GetType())
{
return false;
}
return Equals((AnimatableKey)obj);
}

public override int GetHashCode()
{
unchecked
{
IAnimatable target;
if (!Animatable.TryGetTarget(out target))
{
return Handle?.GetHashCode() ?? 0;
}

return ((target?.GetHashCode() ?? 0) * 397) ^ (Handle?.GetHashCode() ?? 0);
}
}

protected bool Equals(AnimatableKey other)
{
if (!string.Equals(Handle, other.Handle))
{
return false;
}

IAnimatable thisAnimatable;

if (!Animatable.TryGetTarget(out thisAnimatable))
{
return false;
}

IAnimatable thatAnimatable;

if (!other.Animatable.TryGetTarget(out thatAnimatable))
{
return false;
}

return Equals(thisAnimatable, thatAnimatable);
}
}
}
117 changes: 117 additions & 0 deletions Maui.Core/Animation/Animation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System.Collections;
using System.Collections.Generic;

namespace System.Maui
{
public class Animation : IEnumerable
{
readonly List<Animation> _children;
readonly Easing _easing;
readonly Action _finished;
readonly Action<double> _step;
double _beginAt;
double _finishAt;
bool _finishedTriggered;

public Animation()
{
_children = new List<Animation>();
_easing = Easing.Linear;
_step = f => { };
}

public Animation(Action<double> callback, double start = 0.0f, double end = 1.0f, Easing easing = null, Action finished = null)
{
_children = new List<Animation>();
_easing = easing ?? Easing.Linear;
_finished = finished;

Func<double, double> transform = AnimationExtensions.Interpolate(start, end);
_step = f => callback(transform(f));
}

public IEnumerator GetEnumerator()
{
return _children.GetEnumerator();
}

public void Add(double beginAt, double finishAt, Animation animation)
{
if (beginAt < 0 || beginAt > 1)
throw new ArgumentOutOfRangeException("beginAt");

if (finishAt < 0 || finishAt > 1)
throw new ArgumentOutOfRangeException("finishAt");

if (finishAt <= beginAt)
throw new ArgumentException("finishAt must be greater than beginAt");

animation._beginAt = beginAt;
animation._finishAt = finishAt;
_children.Add(animation);
}

public void Commit(IAnimatable owner, string name, uint rate = 16, uint length = 250, Easing easing = null, Action<double, bool> finished = null, Func<bool> repeat = null)
{
owner.Animate(name, this, rate, length, easing, finished, repeat);
}

public Action<double> GetCallback()
{
Action<double> result = f =>
{
_step(_easing.Ease(f));
foreach (Animation animation in _children)
{
if (animation._finishedTriggered)
continue;

double val = Math.Max(0.0f, Math.Min(1.0f, (f - animation._beginAt) / (animation._finishAt - animation._beginAt)));

if (val <= 0.0f) // not ready to process yet
continue;

Action<double> callback = animation.GetCallback();
callback(val);

if (val >= 1.0f)
{
animation._finishedTriggered = true;
if (animation._finished != null)
animation._finished();
}
}
};
return result;
}

internal void ResetChildren()
{
foreach (var anim in _children)
anim._finishedTriggered = false;
}

public Animation Insert(double beginAt, double finishAt, Animation animation)
{
Add(beginAt, finishAt, animation);
return this;
}

public Animation WithConcurrent(Animation animation, double beginAt = 0.0f, double finishAt = 1.0f)
{
animation._beginAt = beginAt;
animation._finishAt = finishAt;
_children.Add(animation);
return this;
}

public Animation WithConcurrent(Action<double> callback, double start = 0.0f, double end = 1.0f, Easing easing = null, double beginAt = 0.0f, double finishAt = 1.0f)
{
var child = new Animation(callback, start, end, easing);
child._beginAt = beginAt;
child._finishAt = finishAt;
_children.Add(child);
return this;
}
}
}
Loading