using System.Collections.Generic; using Ariadne.UnitTests; namespace Ariadne.Vellum.UnitTests { /// /// Counts in a field, and in a local kept across a pause. /// public partial class CountingScript : Arc { public int Count = 0; public string Note = "initial"; protected override void Run(Gates gates) { int waits = 0; wait: while (!gates.Open.Contains("go")) { Count++; waits++; Yield(); } Note = "waited " + waits; } } /// /// Keeps the list its field holds in a local across a pause, and hands it back in another field afterwards. /// public partial class SharingScript : Arc { public List Route = new List(); public List Remembered; protected override void Run(Gates gates) { List kept = Route; wait: while (!gates.Open.Contains("go")) { Yield(); } Remembered = kept; } } /// /// Keeps a converted value in a local across a pause, and another in a field. /// public partial class ConvertedScript : Arc { public Waypoint Destination; protected override void Run(Gates gates) { var start = new Point(1.5, -2); wait: while (!gates.Open.Contains("go")) { Yield(); } Destination = new Waypoint { Name = "back to start", At = start }; } } /// /// Holds the next arc of a chain. /// public sealed partial class ChainScript : Arc { public ChainScript Next; public int Depth; protected override void Run(Gates gates) { } } public abstract partial class MissionScript : Arc { public int Stage; } public sealed partial class ReliefScript : MissionScript { public int Crates; protected override void Run(Gates gates) { } } /// /// Saves and loads its one field by hand, so Ariadne.Generator writes nothing for it. /// public class HandBuiltScript : Arc { public int Held; public HandBuiltScript() { } private HandBuiltScript(IArcReader reader) : base(reader) { int held; if (reader.TryField("Held", out held)) { Held = held; } } protected override void __SaveFields(IArcWriter writer) { base.__SaveFields(writer); writer.Field("Held", Held); } protected override bool __Resume(Gates context, TickTime time) { return true; } protected override void Run(Gates context) { } } /// /// Derives from a generated class but saves itself by hand, so the chain has a class that lists nothing. /// public class HandBuiltUnderMission : MissionScript { protected override void __SaveFields(IArcWriter writer) { base.__SaveFields(writer); } protected override bool __Resume(Gates context, TickTime time) { return true; } protected override void Run(Gates context) { } } /// /// Refers back to the entity holding it. /// public partial class OwnedScript : Arc { public Entity Owner; public int Progress; protected override void Run(Gates gates) { } } /// /// Holds a passage for the scripts that derive from it, which keeps a local across its pause. /// public abstract partial class StepsScript : Arc { public string Note = "idle"; protected void Hold(Gates gates) { int seen = 0; wait: while (!gates.Open.Contains("go")) { seen++; Yield(); } Note = "held " + seen; } } /// /// Runs the passage of the class it derives from. /// public partial class SteppingScript : StepsScript { public int Stage; protected override void Run(Gates gates) { Stage = 1; first: Hold(gates); Stage = 2; } } /// /// Offers a passage for other arcs to run, which keeps a local across its pause. /// public partial class PlantScript : Arc { public int Updates; public string Note = "idle"; public void Update(Gates gates) { int waited = 0; wait: while (!gates.Open.Contains("go")) { waited++; Yield(); } Updates += waited; Note = "updated after " + waited; } protected override void Run(Gates gates) { } } /// /// Runs the passage of another arc, and keeps a local of its own across the call. /// public partial class OperatorScript : Arc { public PlantScript Plant; public string Result; protected override void Run(Gates gates) { int before = 7; update: Plant.Update(gates); Result = "done " + before + " " + Plant.Updates; } } /// /// Sits inside a static class, with a local kept across its pause. /// public static partial class Squad { public partial class Scout : Arc { public int Reported; protected override void Run(Gates gates) { int waited = 0; look: while (!gates.Open.Contains("go")) { waited++; Yield(); } Reported = waited; } } } /// /// Has a type parameter, with a field and a local kept across a pause of its type. /// public partial class Relay : Arc { public T Source; public T Delivered; public void Deliver(Gates gates, T item) { T carried = item; carry: while (!gates.Open.Contains("go")) { Yield(); } Delivered = carried; } protected override void Run(Gates gates) { T held = Source; wait: while (!gates.Open.Contains("go")) { Yield(); } Delivered = held; } } /// /// Runs a passage of an arc whose class has a type parameter. /// public partial class RelayTender : Arc { public Relay Relay; protected override void Run(Gates gates) { string mail = "mail"; deliver: Relay.Deliver(gates, mail); } } /// /// Calls a generic passage with two type arguments, which keeps a local of each across its pause. /// public partial class PassageHolder : Arc { public string Report = ""; private void Hold(Gates gates, X item, string gate) { X held = item; hold: while (!gates.Open.Contains(gate)) { Yield(); } Report += held + ";"; } protected override void Run(Gates gates) { first: Hold(gates, 5, "go1"); second: Hold(gates, "five", "go2"); } } /// /// Has a generic passage that calls an ordinary passage and a generic passage, each keeping a local across its /// pause. /// public partial class NestedRelay : Arc { public string Report = ""; private void Step(Gates gates, string gate) { int spins = 0; step: while (!gates.Open.Contains(gate)) { ++spins; Yield(); } Report += "step" + spins + ";"; } private void Inner(Gates gates, Y item, string gate) { Y deep = item; inner: while (!gates.Open.Contains(gate)) { Yield(); } Report += "inner" + deep + ";"; } private void Outer(Gates gates, X item) { X held = item; first: Step(gates, "a"); second: Inner(gates, held, "b"); } protected override void Run(Gates gates) { start: Outer(gates, 9); } } /// /// Offers a generic passage for other arcs to run, which calls an ordinary passage of its own arc. /// public partial class Greenhouse : Arc { public string Note = ""; private void Step(Gates gates, string gate) { int spins = 0; step: while (!gates.Open.Contains(gate)) { ++spins; Yield(); } Note += "step" + spins + ";"; } public void Grow(Gates gates, X seed, string gate) { X kept = seed; grow: Step(gates, "s"); wait: while (!gates.Open.Contains(gate)) { Yield(); } Note += "grew" + kept + ";"; } protected override void Run(Gates gates) { } } /// /// Runs a generic passage of another arc. /// public partial class Farmer : Arc { public Greenhouse House; protected override void Run(Gates gates) { first: House.Grow(gates, 4, "g1"); } } /// /// Counts its ticks in a field until a gate opens. /// public partial class CounterScript : Arc { public int Counted; protected override void Run(Gates gates) { count: while (!gates.Open.Contains("stop")) { Counted++; Yield(); } } } /// /// Ticks the arc it holds before its own script, which waits for that arc to finish. /// public partial class SupervisorScript : Arc { public CounterScript Child = new CounterScript(); public string Result = "none"; protected override bool TickSelf(Gates gates, TickContext tick) { Child.Tick(gates, tick); return base.TickSelf(gates, tick); } protected override void Run(Gates gates) { wait: while (!Child.Finished) { Yield(); } Result = "child counted " + Child.Counted; } } }