Skip to content

Commit

Permalink
Cleaner branching
Browse files Browse the repository at this point in the history
  • Loading branch information
smoogipoo committed Oct 3, 2024
1 parent 2fa4db1 commit 6988b85
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 71 deletions.
9 changes: 5 additions & 4 deletions osu.Framework/Graphics/TransformSequenceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,13 @@ public static TransformSequence<T> TransformBindableTo<T, TValue, TEasing>(this
public static TransformSequence<T> Loop<T>(this TransformSequence<T> t, double pause, int numIters, params TransformSequence<T>.Generator[] childGenerators)
where T : Drawable
{
TransformSequenceBranch<T> branch = t.CreateBranch();
var branch = t.CreateBranch();

foreach (var gen in childGenerators)
branch.Commit(branch.Head.Continue(gen));
branch.Commit(branch.Head.Loop(pause, numIters));

return t.MergedWith(branch);
return branch.Merge();
}

[Obsolete("For compatibility use only, replacement: X().And().Y().Z().Loop(pause)")]
Expand All @@ -541,12 +541,13 @@ public static TransformSequence<T> Loop<T>(this TransformSequence<T> t, params T
public static TransformSequence<T> Then<T>(this TransformSequence<T> t, double delay, params TransformSequence<T>.Generator[] childGenerators)
where T : Drawable
{
TransformSequenceBranch<T> branch = t.CreateBranch();
var branch = t.CreateBranch();

branch.Commit(branch.Head.Delay(delay));
foreach (var gen in childGenerators)
branch.Commit(branch.Head.Continue(gen));

return t.MergedWith(branch);
return branch.Merge();
}

[Obsolete("For compatibility use only, replacement: X().And().Then().Y().Z()")]
Expand Down
10 changes: 4 additions & 6 deletions osu.Framework/Graphics/TransformableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -715,27 +715,25 @@ public static TransformSequence<T> TransformBindableTo<T, TValue, TEasing>(this
public static TransformSequence<T> Animate<T>(this T transformable, params TransformSequence<T>.Generator[] childGenerators)
where T : Drawable
{
TransformSequence<T> outer = TransformSequence<T>.Create(transformable);
TransformSequenceBranch<T> branch = outer.CreateBranch();
var branch = TransformSequence<T>.Create(transformable).CreateBranch();

foreach (var gen in childGenerators)
branch.Commit(branch.Head.Continue(gen));

return outer.MergedWith(branch);
return branch.Merge();
}

[Obsolete("For compatibility use only, replacement: X.Y().Z().Loop(pause, numIters)")]
public static TransformSequence<T> Loop<T>(this T transformable, double pause, int numIters, params TransformSequence<T>.Generator[] childGenerators)
where T : Drawable
{
TransformSequence<T> outer = TransformSequence<T>.Create(transformable);
TransformSequenceBranch<T> branch = outer.CreateBranch();
var branch = TransformSequence<T>.Create(transformable).CreateBranch();

foreach (var gen in childGenerators)
branch.Commit(branch.Head.Continue(gen));
branch.Commit(branch.Head.Loop(pause, numIters));

return outer.MergedWith(branch);
return branch.Merge();
}

[Obsolete("For compatibility use only, replacement: X.Y().Z().Loop(pause)")]
Expand Down
123 changes: 62 additions & 61 deletions osu.Framework/Graphics/Transforms/TransformSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@

namespace osu.Framework.Graphics.Transforms
{
internal static class TransformSequenceHelpers
{
private static ulong id = 1;

public static ulong GetNextId() => Interlocked.Increment(ref id);
}

public readonly struct TransformSequence<T>
where T : class, ITransformable
{
Expand Down Expand Up @@ -89,9 +82,12 @@ public static TransformSequence<T> Create(T target)
/// <param name="transform">The transform.</param>
public static TransformSequence<T> Create(Transform transform)
{
TransformSequenceException.ThrowIfInvalidTransform<T>(transform);
if (transform.Target is null)
throwTargetIsNull();

if (transform.Target is not T target)
throwTargetTypeMismatch(typeof(T), transform.Target.GetType());

T target = (T)transform.Target;
TransformSequence<T> sequence = Create(target);

transform.SequenceID = sequence.id;
Expand All @@ -107,6 +103,14 @@ public static TransformSequence<T> Create(Transform transform)
length = sequence.length + 1,
transform = transform
};

[DoesNotReturn]
static void throwTargetIsNull()
=> throw new ArgumentException("Transform target cannot be null.");

[DoesNotReturn]
static void throwTargetTypeMismatch(Type expected, Type actual)
=> throw new ArgumentException($"Transform target was expected to be of type '{expected.ReadableName()}' but was '{actual.ReadableName()}'.");
}

/// <summary>
Expand Down Expand Up @@ -157,28 +161,6 @@ public TransformSequence<T> Delay(double delay) => this with
currentTime = currentTime + delay
};

/// <summary>
/// Creates an empty branch from the current time.
/// </summary>
public TransformSequenceBranch<T> CreateBranch() => new TransformSequenceBranch<T>(this with
{
startTime = currentTime,
currentTime = currentTime,
endTime = currentTime,
length = 0
});

/// <summary>
/// Continues with the result of merging a branch into the current sequence.
/// </summary>
/// <param name="branch">The branch to merge.</param>
public TransformSequence<T> MergedWith(TransformSequenceBranch<T> branch) => this with
{
endTime = Math.Max(endTime, branch.Head.endTime),
length = length + branch.Head.length,
transform = branch.Head.transform
};

/// <summary>
/// Repeats all added transforms indefinitely.
/// </summary>
Expand Down Expand Up @@ -249,6 +231,17 @@ public TransformSequence<T> Loop(double pause, int numIters)
return this;
}

/// <summary>
/// Creates an empty branch from the current time.
/// </summary>
public Branch CreateBranch() => new Branch(this with
{
startTime = currentTime,
currentTime = currentTime,
endTime = currentTime,
length = 0
});

public TransformSequence<T> Finally(Action<T> function)
{
OnComplete(function);
Expand Down Expand Up @@ -277,6 +270,41 @@ private TransformSequenceEventHandler getOrCreateEventHandler()
return handler;
}

public ref struct Branch
{
/// <summary>
/// The current head.
/// </summary>
public TransformSequence<T> Head { get; private set; }

/// <summary>
/// The sequence which this branch is based off.
/// </summary>
private readonly TransformSequence<T> root;

internal Branch(TransformSequence<T> root)
{
this.root = root;
Head = root;
}

/// <summary>
/// Appends a commit.
/// </summary>
/// <param name="head">The new head.</param>
public void Commit(TransformSequence<T> head) => Head = head;

/// <summary>
/// Continues with the result of merging this branch into the original sequence.
/// </summary>
public TransformSequence<T> Merge() => root with
{
endTime = Math.Max(root.endTime, Head.endTime),
length = root.length + Head.length,
transform = Head.transform
};
}

/// <summary>
/// A delegate that generates a new <see cref="TransformSequence{T}"/> on a given <paramref name="origin"/>.
/// </summary>
Expand All @@ -285,37 +313,10 @@ private TransformSequenceEventHandler getOrCreateEventHandler()
public delegate TransformSequence<T> Generator(T origin);
}

public ref struct TransformSequenceBranch<T>(TransformSequence<T> head)
where T : class, ITransformable
{
public TransformSequence<T> Head { get; private set; } = head;

public void Commit(TransformSequence<T> head) => Head = head;
}

public class TransformSequenceException : Exception
internal static class TransformSequenceHelpers
{
public TransformSequenceException(string message)
: base(message)
{
}

public static void ThrowIfInvalidTransform<T>(Transform transform)
where T : class, ITransformable
{
if (transform.Target is null)
throwTargetIsNull();

if (transform.Target is not T)
throwTargetTypeMismatch(typeof(T), transform.Target.GetType());
}

[DoesNotReturn]
private static void throwTargetIsNull()
=> throw new TransformSequenceException("Transform target cannot be null.");
private static ulong id = 1;

[DoesNotReturn]
private static void throwTargetTypeMismatch(Type expected, Type actual)
=> throw new TransformSequenceException($"Transform target was expected to be of type '{expected.ReadableName()}' but was '{actual.ReadableName()}'.");
public static ulong GetNextId() => Interlocked.Increment(ref id);
}
}

0 comments on commit 6988b85

Please sign in to comment.