using System;
using System.Collections.Generic;
using Vellum;
namespace Ariadne.Vellum.UnitTests
{
///
/// The context the latch wait scripts run in, with the latches they wait on and a log they write to.
///
public class Lounge
{
public Latch Door = new Latch();
public Latch Alarm = new Latch();
public List Log = new List();
}
public class LoungeConverter : SaveConverter
{
public override SaveNode Write(Lounge value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["door"] = session.ToNode(value.Door);
returnMe.Entries["alarm"] = session.ToNode(value.Alarm);
returnMe.Entries["log"] = session.ToNode(value.Log);
return returnMe;
}
public override Lounge Read(SaveNode node, SaveSession session)
{
var returnMe = new Lounge();
session.Publish(node, returnMe);
returnMe.Door = session.FromNode(node.RequireEntry("door"));
returnMe.Alarm = session.FromNode(node.RequireEntry("alarm"));
returnMe.Log = session.FromNode>(node.RequireEntry("log"));
return returnMe;
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode door;
SaveNode alarm;
SaveNode log;
if (!node.TryGetEntry("door", out door) || !node.TryGetEntry("alarm", out alarm)
|| !node.TryGetEntry("log", out log))
{
return false;
}
children.Add(door, typeof(Latch));
children.Add(alarm, typeof(Latch));
children.Add(log, typeof(List));
return true;
}
}
///
/// A lounge and what runs in it, which are saved and loaded together.
///
public class LoungeScene
{
public Lounge Lounge;
public ContentType Content;
}
public class LoungeSceneConverter : SaveConverter>
{
public override SaveNode Write(LoungeScene value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["lounge"] = session.ToNode(value.Lounge);
returnMe.Entries["content"] = session.ToNode(value.Content);
return returnMe;
}
public override LoungeScene Read(SaveNode node, SaveSession session)
{
var returnMe = new LoungeScene();
session.Publish(node, returnMe);
returnMe.Lounge = session.FromNode(node.RequireEntry("lounge"));
returnMe.Content = session.FromNode(node.RequireEntry("content"));
return returnMe;
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode lounge;
SaveNode content;
if (!node.TryGetEntry("lounge", out lounge) || !node.TryGetEntry("content", out content))
{
return false;
}
children.Add(lounge, typeof(Lounge));
children.Add(content, typeof(ContentType));
return true;
}
}
///
/// Waits for the door to be set, then logs.
///
public partial class LoungeDoorScript : Arc
{
protected override void Run(Lounge lounge)
{
lounge.Log.Add("start");
door:
Wait(lounge.Door);
lounge.Log.Add("door");
}
}
///
/// Waits for the door to be clear, then logs.
///
public partial class LoungeClearScript : Arc
{
protected override void Run(Lounge lounge)
{
lounge.Log.Add("start");
clear:
Wait(!lounge.Door);
lounge.Log.Add("clear");
}
}
///
/// Waits for the alarm with a time limit, and logs which came first.
///
public partial class LoungeTimedScript : Arc
{
public TimeSpan Limit = TimeSpan.FromSeconds(2);
protected override void Run(Lounge lounge)
{
lounge.Log.Add("start");
alarm:
Condition got = Wait(lounge.Alarm, timeout: Limit);
lounge.Log.Add(got == null ? "timed out" : "alarm");
}
}
///
/// Waits for both latches, then logs.
///
public partial class LoungeBothScript : Arc
{
protected override void Run(Lounge lounge)
{
lounge.Log.Add("start");
both:
WaitAll(lounge.Door, lounge.Alarm);
lounge.Log.Add("both");
}
}
///
/// Waits for either latch, and logs which one it was.
///
public partial class LoungeEitherScript : Arc
{
protected override void Run(Lounge lounge)
{
lounge.Log.Add("start");
either:
Condition got = WaitAny(lounge.Door, lounge.Alarm);
lounge.Log.Add(got == lounge.Alarm ? "alarm" : "door");
}
}
///
/// Waits for the door, then sleeps for a long time.
///
public partial class LoungeThenSleepScript : Arc
{
protected override void Run(Lounge lounge)
{
door:
Wait(lounge.Door);
lounge.Log.Add("door");
nap:
Wait(TimeSpan.FromSeconds(100));
lounge.Log.Add("rested");
}
}
}