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

Add ScheduleAfterChildren()-API to Containers #802

Merged
merged 3 commits into from Jun 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions osu.Framework/Graphics/Containers/Container.cs
Expand Up @@ -20,6 +20,8 @@
using System.Linq;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.MathUtils;
using osu.Framework.Threading;
using osu.Framework.Statistics;

namespace osu.Framework.Graphics.Containers
{
Expand Down Expand Up @@ -91,11 +93,19 @@ private void loadChild(Drawable child)
child.Parent = this;
}

protected override void LoadComplete()
{
schedulerAfterChildren?.SetCurrentThread(MainThread);
base.LoadComplete();
}

protected override void Dispose(bool isDisposing)
{
InternalChildren?.ForEach(c => c.Dispose());

OnAutoSize = null;
schedulerAfterChildren?.Dispose();
schedulerAfterChildren = null;

base.Dispose(isDisposing);
}
Expand Down Expand Up @@ -339,6 +349,10 @@ protected void AddInternal(IEnumerable<Drawable> range)

#region Updating (per-frame periodic)

private Scheduler schedulerAfterChildren;

protected Scheduler SchedulerAfterChildren => schedulerAfterChildren ?? (schedulerAfterChildren = new Scheduler(MainThread));

/// <summary>
/// Updates the life status of <see cref="InternalChildren"/> according to their
/// <see cref="IHasLifetime.IsAlive"/> property.
Expand Down Expand Up @@ -388,6 +402,11 @@ public override bool UpdateSubTree()
foreach (Drawable child in internalChildren.AliveItems)
if (child.IsLoaded) child.UpdateSubTree();

if (schedulerAfterChildren != null)
{
int amountScheduledTasks = schedulerAfterChildren.Update();
FrameStatistics.Increment(StatisticsCounterType.ScheduleInvk, amountScheduledTasks);
}
UpdateAfterChildren();

updateChildrenSizeDependencies();
Expand Down Expand Up @@ -613,6 +632,8 @@ public override Drawable Delay(double duration, bool propagateChildren = false)
return this;
}

public ScheduledDelegate ScheduleAfterChildren(Action action) => SchedulerAfterChildren.AddDelayed(action, TransformDelay);

public override void Flush(bool propagateChildren = false, Type flushType = null)
{
base.Flush(propagateChildren, flushType);
Expand Down
28 changes: 14 additions & 14 deletions osu.Framework/Graphics/Drawable.cs
Expand Up @@ -210,8 +210,8 @@ private bool loadComplete()
{
if (loadState < LoadState.Loaded) return false;

mainThread = Thread.CurrentThread;
scheduler?.SetCurrentThread(mainThread);
MainThread = Thread.CurrentThread;
scheduler?.SetCurrentThread(MainThread);

Invalidate();
loadState = LoadState.Alive;
Expand Down Expand Up @@ -314,13 +314,13 @@ public virtual int Compare(Drawable x, Drawable y)
internal event Action<Drawable> OnInvalidate;

private Scheduler scheduler;
private Thread mainThread;
internal Thread MainThread { get; private set; }

/// <summary>
/// A lazily-initialized scheduler used to schedule tasks to be invoked in future <see cref="Update"/>s calls.
/// The tasks are invoked at the beginning of the <see cref="Update"/> method before anything else.
/// </summary>
protected Scheduler Scheduler => scheduler ?? (scheduler = new Scheduler(mainThread));
protected Scheduler Scheduler => scheduler ?? (scheduler = new Scheduler(MainThread));

private LifetimeList<ITransform> transforms;

Expand Down Expand Up @@ -377,7 +377,7 @@ public virtual bool UpdateSubTree()
if (loadState < LoadState.Alive)
if (!loadComplete()) return false;

transformDelay = 0;
TransformDelay = 0;

//todo: this should be moved to after the IsVisible condition once we have TOL for transforms (and some better logic).
updateTransforms();
Expand Down Expand Up @@ -1931,7 +1931,7 @@ public IMouseState Clone()

#region Transforms

private double transformDelay;
internal double TransformDelay { get; private set; }

public virtual void ClearTransforms(bool propagateChildren = false)
{
Expand All @@ -1943,11 +1943,11 @@ public virtual Drawable Delay(double duration, bool propagateChildren = false)
{
if (duration == 0) return this;

transformDelay += duration;
TransformDelay += duration;
return this;
}

public ScheduledDelegate Schedule(Action action) => Scheduler.AddDelayed(action, transformDelay);
public ScheduledDelegate Schedule(Action action) => Scheduler.AddDelayed(action, TransformDelay);

/// <summary>
/// Flush specified transforms, using the last available values (ignoring current clock time).
Expand Down Expand Up @@ -1979,7 +1979,7 @@ public virtual void Flush(bool propagateChildren = false, Type flushType = null)

public virtual Drawable DelayReset()
{
Delay(-transformDelay);
Delay(-TransformDelay);
return this;
}

Expand All @@ -2000,14 +2000,14 @@ public virtual Drawable DelayReset()
/// <exception cref="InvalidOperationException">Absolute sequences should never be nested inside another existing sequence.</exception>
public TransformSequence BeginAbsoluteSequence(double startOffset = 0, bool recursive = false)
{
if (transformDelay != 0) throw new InvalidOperationException($"Cannot use {nameof(BeginAbsoluteSequence)} with a non-zero transform delay already present");
if (TransformDelay != 0) throw new InvalidOperationException($"Cannot use {nameof(BeginAbsoluteSequence)} with a non-zero transform delay already present");
return new TransformSequence(this, -(Clock?.CurrentTime ?? 0) + startOffset, recursive);
}

public void Loop(float delay = 0)
{
foreach (var t in Transforms)
t.Loop(Math.Max(0, transformDelay + delay - t.Duration));
t.Loop(Math.Max(0, TransformDelay + delay - t.Duration));
}

/// <summary>
Expand Down Expand Up @@ -2069,7 +2069,7 @@ public virtual void Show()
/// <summary>
/// The time to use for starting transforms which support <see cref="Delay(double, bool)"/>
/// </summary>
protected double TransformStartTime => (Clock?.CurrentTime ?? 0) + transformDelay;
protected double TransformStartTime => (Clock?.CurrentTime ?? 0) + TransformDelay;

public void TransformTo<TValue>(Func<TValue> currentValue, TValue newValue, double duration, EasingTypes easing, Transform<TValue> transform) where TValue : struct, IEquatable<TValue>
{
Expand All @@ -2087,7 +2087,7 @@ public virtual void Show()

TValue startValue = currentValue();

if (transformDelay == 0)
if (TransformDelay == 0)
{
Transforms.RemoveAll(t => t.GetType() == type);

Expand Down Expand Up @@ -2124,7 +2124,7 @@ private void addTransform(ITransform transform)
}

//we have no duration and do not need to be delayed, so we can just apply ourselves and be gone.
bool canApplyInstant = transform.Duration == 0 && transformDelay == 0;
bool canApplyInstant = transform.Duration == 0 && TransformDelay == 0;

//we should also immediately apply any transforms that have already started to avoid potentially applying them one frame too late.
if (canApplyInstant || transform.StartTime < Time.Current)
Expand Down