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"); } } }