From 3f44766bd4471ca931c8b34fd27a5416b3d5b87b Mon Sep 17 00:00:00 2001 From: Gandifil Date: Mon, 22 Jan 2024 19:03:17 +0300 Subject: [PATCH 1/4] Move extracting linear operations into special class. --- .../LinearOperations.cs | 21 ++++++++++++++++++ src/cs/MonoGame.Extended.Tweening/Tween.cs | 10 ++++----- .../MonoGame.Extended.Tweening/TweenMember.cs | 22 ++++--------------- 3 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 src/cs/MonoGame.Extended.Tweening/LinearOperations.cs diff --git a/src/cs/MonoGame.Extended.Tweening/LinearOperations.cs b/src/cs/MonoGame.Extended.Tweening/LinearOperations.cs new file mode 100644 index 00000000..12a03a8e --- /dev/null +++ b/src/cs/MonoGame.Extended.Tweening/LinearOperations.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq.Expressions; + +namespace MonoGame.Extended.Tweening; + +public class LinearOperations +{ + static LinearOperations() + { + var a = Expression.Parameter(typeof(T)); + var b = Expression.Parameter(typeof(T)); + var c = Expression.Parameter(typeof(float)); + Add = Expression.Lambda>(Expression.Add(a, b), a, b).Compile(); + Subtract = Expression.Lambda>(Expression.Subtract(a, b), a, b).Compile(); + Multiply = Expression.Lambda>(Expression.Multiply(a, c), a, c).Compile(); + } + + public static Func Add { get; } + public static Func Subtract { get; } + public static Func Multiply { get; } +} diff --git a/src/cs/MonoGame.Extended.Tweening/Tween.cs b/src/cs/MonoGame.Extended.Tweening/Tween.cs index b15a30ee..115b66da 100644 --- a/src/cs/MonoGame.Extended.Tweening/Tween.cs +++ b/src/cs/MonoGame.Extended.Tweening/Tween.cs @@ -4,9 +4,9 @@ using Microsoft.Xna.Framework; namespace MonoGame.Extended.Tweening { public class Tween : Tween - where T : struct + where T : struct { - internal Tween(object target, float duration, float delay, TweenMember member, T endValue) + internal Tween(object target, float duration, float delay, TweenMember member, T endValue) : base(target, duration, delay) { Member = member; @@ -23,12 +23,12 @@ namespace MonoGame.Extended.Tweening protected override void Initialize() { _startValue = Member.Value; - _range = TweenMember.Subtract(_endValue, _startValue); + _range = LinearOperations.Subtract(_endValue, _startValue); } protected override void Interpolate(float n) { - var value = TweenMember.Add(_startValue, TweenMember.Multiply(_range, n)); + var value = LinearOperations.Add(_startValue, LinearOperations.Multiply(_range, n)); Member.Value = value; } @@ -189,4 +189,4 @@ namespace MonoGame.Extended.Tweening } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Tweening/TweenMember.cs b/src/cs/MonoGame.Extended.Tweening/TweenMember.cs index 59414e17..adcee598 100644 --- a/src/cs/MonoGame.Extended.Tweening/TweenMember.cs +++ b/src/cs/MonoGame.Extended.Tweening/TweenMember.cs @@ -16,29 +16,15 @@ namespace MonoGame.Extended.Tweening } public abstract class TweenMember : TweenMember - where T : struct + where T : struct { - static TweenMember() - { - var a = Expression.Parameter(typeof(T)); - var b = Expression.Parameter(typeof(T)); - var c = Expression.Parameter(typeof(float)); - Add = Expression.Lambda>(Expression.Add(a, b), a, b).Compile(); - Subtract = Expression.Lambda>(Expression.Subtract(a, b), a, b).Compile(); - Multiply = Expression.Lambda>(Expression.Multiply(a, c), a, c).Compile(); - } - - public static Func Add { get; } - public static Func Subtract { get; } - public static Func Multiply { get; } - protected TweenMember(object target, Func getMethod, Action setMethod) : base(target) { _getMethod = getMethod; - _setMethod = setMethod; + _setMethod = setMethod; } - + private readonly Func _getMethod; private readonly Action _setMethod; @@ -48,4 +34,4 @@ namespace MonoGame.Extended.Tweening set { _setMethod(Target, value); } } } -} \ No newline at end of file +} From 60d2fdfd1eab14d1977305f868cfa7928de183ab Mon Sep 17 00:00:00 2001 From: Gandifil Date: Mon, 22 Jan 2024 19:24:53 +0300 Subject: [PATCH 2/4] Move impls of linear tweening into special class. --- .../MonoGame.Extended.Tweening/LinearTween.cs | 23 +++++++++++++++++++ src/cs/MonoGame.Extended.Tweening/Tween.cs | 14 +++-------- src/cs/MonoGame.Extended.Tweening/Tweener.cs | 4 ++-- 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 src/cs/MonoGame.Extended.Tweening/LinearTween.cs diff --git a/src/cs/MonoGame.Extended.Tweening/LinearTween.cs b/src/cs/MonoGame.Extended.Tweening/LinearTween.cs new file mode 100644 index 00000000..8469a135 --- /dev/null +++ b/src/cs/MonoGame.Extended.Tweening/LinearTween.cs @@ -0,0 +1,23 @@ +namespace MonoGame.Extended.Tweening; + +public class LinearTween: Tween + where T: struct +{ + private T _range; + + internal LinearTween(object target, float duration, float delay, TweenMember member, T endValue) : base(target, duration, delay, member, endValue) + { + } + + protected override void Initialize() + { + base.Initialize(); + _range = LinearOperations.Subtract(_endValue, _startValue); + } + + protected override void Interpolate(float n) + { + var value = LinearOperations.Add(_startValue, LinearOperations.Multiply(_range, n)); + Member.Value = value; + } +} diff --git a/src/cs/MonoGame.Extended.Tweening/Tween.cs b/src/cs/MonoGame.Extended.Tweening/Tween.cs index 115b66da..ad292518 100644 --- a/src/cs/MonoGame.Extended.Tweening/Tween.cs +++ b/src/cs/MonoGame.Extended.Tweening/Tween.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework; namespace MonoGame.Extended.Tweening { - public class Tween : Tween + public abstract class Tween : Tween where T : struct { internal Tween(object target, float duration, float delay, TweenMember member, T endValue) @@ -16,20 +16,12 @@ namespace MonoGame.Extended.Tweening public TweenMember Member { get; } public override string MemberName => Member.Name; - private T _startValue; - private T _endValue; - private T _range; + protected T _startValue; + protected T _endValue; protected override void Initialize() { _startValue = Member.Value; - _range = LinearOperations.Subtract(_endValue, _startValue); - } - - protected override void Interpolate(float n) - { - var value = LinearOperations.Add(_startValue, LinearOperations.Multiply(_range, n)); - Member.Value = value; } protected override void Swap() diff --git a/src/cs/MonoGame.Extended.Tweening/Tweener.cs b/src/cs/MonoGame.Extended.Tweening/Tweener.cs index 12895cea..893a5d3c 100644 --- a/src/cs/MonoGame.Extended.Tweening/Tweener.cs +++ b/src/cs/MonoGame.Extended.Tweening/Tweener.cs @@ -35,7 +35,7 @@ namespace MonoGame.Extended.Tweening activeTween?.Cancel(); AllocationCount++; - var tween = new Tween(target, duration, delay, member, toValue); + var tween = new LinearTween(target, duration, delay, member, toValue); _activeTweens.Add(tween); return tween; } @@ -112,4 +112,4 @@ namespace MonoGame.Extended.Tweening throw new InvalidOperationException($"'{memberName}' is not a property or field of the target"); } } -} \ No newline at end of file +} From f961461a67a529a7bb19e3f451125c2bccd17b64 Mon Sep 17 00:00:00 2001 From: Gandifil Date: Mon, 22 Jan 2024 19:32:13 +0300 Subject: [PATCH 3/4] Add ColorTween --- src/cs/MonoGame.Extended.Tweening/ColorTween.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/cs/MonoGame.Extended.Tweening/ColorTween.cs diff --git a/src/cs/MonoGame.Extended.Tweening/ColorTween.cs b/src/cs/MonoGame.Extended.Tweening/ColorTween.cs new file mode 100644 index 00000000..2e98e5d1 --- /dev/null +++ b/src/cs/MonoGame.Extended.Tweening/ColorTween.cs @@ -0,0 +1,15 @@ +using Microsoft.Xna.Framework; + +namespace MonoGame.Extended.Tweening; + +public class ColorTween: Tween +{ + internal ColorTween(object target, float duration, float delay, TweenMember member, Color endValue) : base(target, duration, delay, member, endValue) + { + } + + protected override void Interpolate(float n) + { + Member.Value = Color.Lerp(_startValue, _endValue, n); + } +} From a2e3aacb9070379c1d31d7885c01b199971f856a Mon Sep 17 00:00:00 2001 From: Gandifil Date: Mon, 22 Jan 2024 20:10:34 +0300 Subject: [PATCH 4/4] Add special TweenTo. --- src/cs/MonoGame.Extended.Tweening/Tweener.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/cs/MonoGame.Extended.Tweening/Tweener.cs b/src/cs/MonoGame.Extended.Tweening/Tweener.cs index 893a5d3c..1e17efae 100644 --- a/src/cs/MonoGame.Extended.Tweening/Tweener.cs +++ b/src/cs/MonoGame.Extended.Tweening/Tweener.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using Microsoft.Xna.Framework; namespace MonoGame.Extended.Tweening { @@ -26,6 +27,21 @@ namespace MonoGame.Extended.Tweening public Tween TweenTo(TTarget target, Expression> expression, TMember toValue, float duration, float delay = 0f) where TTarget : class where TMember : struct + { + switch (toValue) + { + case Color toValueColor: + return (Tween)(object)TweenTo(target, expression as Expression>, toValueColor, duration, delay); + default: + return TweenTo>(target, expression, toValue, duration, delay); + } + + } + + public Tween TweenTo(TTarget target, Expression> expression, TMember toValue, float duration, float delay = 0f) + where TTarget : class + where TMember : struct + where TTween : Tween { var memberExpression = (MemberExpression)expression.Body; var memberInfo = memberExpression.Member; @@ -35,7 +51,7 @@ namespace MonoGame.Extended.Tweening activeTween?.Cancel(); AllocationCount++; - var tween = new LinearTween(target, duration, delay, member, toValue); + var tween = (TTween)Activator.CreateInstance(typeof(TTween), target, duration, delay, member, toValue); _activeTweens.Add(tween); return tween; }