Skip to content

Instantly share code, notes, and snippets.

@renaudbedard
Created May 6, 2015 14:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save renaudbedard/3904b9c7e853cf78959c to your computer and use it in GitHub Desktop.
Save renaudbedard/3904b9c7e853cf78959c to your computer and use it in GitHub Desktop.
Stateful and stateless waiting classes
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using XnaCommons.Structure;
using XnaCommons.Tools;
namespace XnaCommons.Components
{
public static class Waiters
{
static readonly ISceneService Scene = GameHelper.GetService<ISceneService>();
class TimeKeeper
{
public TimeSpan Elapsed;
}
public static void WaitForGuide(Action onValid)
{
Scene.Active.AddComponent(new Waiter(Scene.Active, () => !Guide.IsVisible, onValid));
}
public static void Wait(double secondsToWait, Action onValid)
{
Scene.Active.AddComponent(new Waiter<TimeKeeper>(Scene.Active,
waited => waited.Elapsed.TotalSeconds > secondsToWait,
(elapsed, waited) => waited.Elapsed += elapsed,
onValid));
}
public static void Interpolate(double durationSeconds, Action<float> assignation)
{
Interpolate(durationSeconds, assignation, ActionHelper.NullAction);
}
public static void Interpolate(double durationSeconds, Action<float> assignation, Action onComplete)
{
Scene.Active.AddComponent(new Waiter<TimeKeeper>(Scene.Active,
waited => waited.Elapsed.TotalSeconds > durationSeconds,
(elapsed, waited) =>
{
waited.Elapsed += elapsed;
assignation((float)(waited.Elapsed.TotalSeconds / durationSeconds));
},
onComplete));
}
}
class Waiter : IGameComponent, IUpdateable
{
readonly Scene scene;
readonly Func<bool> condition;
readonly Action<TimeSpan> whileWaiting;
readonly Action onValid;
internal Waiter(Scene scene, Func<bool> condition, Action onValid) : this(scene, condition, ActionHelper.NullAction, onValid) { }
internal Waiter(Scene scene, Func<bool> condition, Action<TimeSpan> whileWaiting) : this(scene, condition, whileWaiting, ActionHelper.NullAction) { }
internal Waiter(Scene scene, Func<bool> condition, Action<TimeSpan> whileWaiting, Action onValid)
{
this.scene = scene;
this.condition = condition;
this.whileWaiting = whileWaiting;
this.onValid = onValid;
}
public void Update(GameTime gameTime)
{
if (condition())
{
onValid();
scene.RemoveComponent(this);
}
else
whileWaiting(gameTime.ElapsedGameTime);
}
public void Initialize() { }
public bool Enabled { get { return true; } }
public event EventHandler EnabledChanged;
public event EventHandler UpdateOrderChanged;
public int UpdateOrder { get { return 0; } }
}
class Waiter<T> : IGameComponent, IUpdateable where T : class, new()
{
readonly Scene scene;
readonly Func<T, bool> condition;
readonly Action<TimeSpan, T> whileWaiting;
readonly Action onValid;
readonly T state;
internal Waiter(Scene scene, Func<T, bool> condition, Action onValid) : this(scene, condition, ActionHelper.NullAction, onValid, new T()) { }
internal Waiter(Scene scene, Func<T, bool> condition, Action<TimeSpan, T> whileWaiting) : this(scene, condition, whileWaiting, ActionHelper.NullAction, new T()) { }
internal Waiter(Scene scene, Func<T, bool> condition, Action<TimeSpan, T> whileWaiting, Action onValid) : this(scene, condition, whileWaiting, onValid, new T()) { }
internal Waiter(Scene scene, Func<T, bool> condition, Action<TimeSpan, T> whileWaiting, T state) : this(scene, condition, whileWaiting, ActionHelper.NullAction, state) { }
internal Waiter(Scene scene, Func<T, bool> condition, Action<TimeSpan, T> whileWaiting, Action onValid, T state)
{
this.scene = scene;
this.condition = condition;
this.whileWaiting = whileWaiting;
this.onValid = onValid;
this.state = state;
}
public void Update(GameTime gameTime)
{
if (condition(state))
{
onValid();
scene.RemoveComponent(this);
}
else
whileWaiting(gameTime.ElapsedGameTime, state);
}
public void Initialize() { }
public bool Enabled { get { return true; } }
public event EventHandler EnabledChanged;
public event EventHandler UpdateOrderChanged;
public int UpdateOrder { get { return 0; } }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment