using System;
using System.Collections.Generic;
namespace Ariadne.UnitTests
{
///
/// The context the condition wait scripts run in, with the latches they wait on and a log they write to.
///
public class LatchWorld
{
public readonly Latch Door = new Latch();
public readonly Latch Alarm = new Latch();
public readonly List Log = new List();
public TimeSpan Limit = TimeSpan.FromSeconds(1);
}
///
/// Waits for the door to be set, then logs.
///
public partial class SingleLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
world.Log.Add("start");
first:
Wait(world.Door);
world.Log.Add("door");
}
}
///
/// Waits for the door to be clear, then logs.
///
public partial class ClearLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
world.Log.Add("start");
first:
Wait(!world.Door);
world.Log.Add("clear");
}
}
///
/// Waits for the door three times, with a local counting the trips.
///
public partial class LoopedLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
int count = 0;
while (count < 3)
{
spin:
Wait(world.Door);
++count;
world.Log.Add("door " + count);
}
}
}
///
/// Waits for the door, then sleeps for a long time.
///
public partial class LatchThenSleepScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Wait(world.Door);
world.Log.Add("door");
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Waits for the door or the limit, and logs which came first.
///
public partial class TimedLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition got = Wait(world.Door, timeout: world.Limit);
world.Log.Add(got == world.Door ? "door" : "timeout");
}
}
///
/// Waits for the door to be clear or the limit, and logs which came first.
///
public partial class TimedClearScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition got = Wait(!world.Door, timeout: world.Limit);
world.Log.Add(got == null ? "timeout" : "clear");
}
}
///
/// Waits for the door or the limit, then sleeps, so a late change to the door has to leave the sleep alone.
///
public partial class TimedLatchThenSleepScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Wait(world.Door, timeout: world.Limit);
world.Log.Add("through");
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Waits for the door unless told to skip it, and then sleeps, so a restart can send it past the wait.
///
public partial class RestartableLatchScript : Arc
{
public bool Skip;
protected override void Run(LatchWorld world)
{
if (!Skip)
{
first:
Wait(world.Door);
world.Log.Add("door");
}
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Waits for the door in a passage unless told to skip it, and then sleeps.
///
public partial class RestartableLatchPassageScript : Arc
{
public bool Skip;
private void Watch(LatchWorld world)
{
inner:
Wait(world.Door);
world.Log.Add("door");
}
protected override void Run(LatchWorld world)
{
if (!Skip)
{
call:
Watch(world);
}
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Offers a passage for other arcs to run, which waits for the door.
///
public partial class LatchLookoutScript : Arc
{
public void Watch(LatchWorld world)
{
watch:
Wait(world.Door);
world.Log.Add("door");
}
protected override void Run(LatchWorld world)
{
}
}
///
/// Runs the passage of another arc that waits for the door, unless told to skip it, and then sleeps.
///
public partial class LatchRelayScript : Arc
{
public LatchLookoutScript Lookout;
public bool Skip;
protected override void Run(LatchWorld world)
{
if (!Skip)
{
relay:
Lookout.Watch(world);
}
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Waits for either latch, and logs which one it was.
///
public partial class AnyLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition got = WaitAny(world.Door, world.Alarm);
world.Log.Add(got == world.Alarm ? "alarm" : "door");
}
}
///
/// Waits for the door to be set or clear, which is always so.
///
public partial class AnyOrInverseScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
WaitAny(world.Door, !world.Door);
world.Log.Add("through");
}
}
///
/// Waits for either latch, then sleeps, so a late change to either has to leave the sleep alone.
///
public partial class AnyLatchThenSleepScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
WaitAny(world.Door, world.Alarm);
world.Log.Add("through");
nap:
Wait(TimeSpan.FromSeconds(100));
world.Log.Add("rested");
}
}
///
/// Waits for both latches, and logs what the wait returned.
///
public partial class AllLatchesScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition last = WaitAll(world.Door, world.Alarm);
world.Log.Add(last == world.Alarm ? "all set" : "other");
}
}
///
/// Waits for the door to be set and the alarm to be clear.
///
public partial class DoorOpenAlarmClearScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
WaitAll(world.Door, !world.Alarm);
world.Log.Add("ready");
}
}
///
/// Waits for the door to be both set and clear, which can't happen.
///
public partial class ContradictoryAllScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
WaitAll(world.Door, !world.Door);
world.Log.Add("never");
}
}
///
/// Waits for either latch or the limit, and logs which came first.
///
public partial class TimedAnyLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition got = WaitAny(timeout: world.Limit, world.Door, world.Alarm);
world.Log.Add(got == null ? "timeout" : got == world.Alarm ? "alarm" : "door");
}
}
///
/// Waits for both latches or the limit, and logs which came first.
///
public partial class TimedAllLatchesScript : Arc
{
protected override void Run(LatchWorld world)
{
first:
Condition got = WaitAll(world.Limit, world.Door, world.Alarm);
world.Log.Add(got == null ? "timeout" : "all set");
}
}
///
/// Takes the condition a wait ended on into a field it assigned earlier.
///
public partial class AssignedLatchScript : Arc
{
public Condition Last;
protected override void Run(LatchWorld world)
{
first:
Last = Wait(world.Door, timeout: world.Limit);
world.Log.Add(Last == null ? "timeout" : "door");
}
}
///
/// Returns the condition a wait ended on from a passage.
///
public partial class ReturnedLatchScript : Arc
{
protected override void Run(LatchWorld world)
{
call:
Condition got = Pick(world);
world.Log.Add(got == null ? "timeout" : "door");
}
private Condition Pick(LatchWorld world)
{
inner:
return Wait(world.Door, timeout: world.Limit);
}
}
}