using System.Collections.Generic; namespace Ariadne.UnitTests { /// /// Calls one generic passage with two type arguments, which keeps a local of each across its pause. /// public partial class DualHolder : Arc { public string Report = ""; private void Hold(ArcTests.Gates gates, X item, string gate) { X held = item; var seen = new List(); hold: while (!gates.Open.Contains(gate)) { seen.Add(held); Yield(); } Report += held + "x" + seen.Count + ";"; } protected override void Run(ArcTests.Gates gates) { numbers: Hold(gates, 7, "go1"); words: Hold(gates, "seven", "go2"); } } /// /// Has a generic passage that calls an ordinary passage and generic passages of two type arguments, and carries on /// with an ordinary call after it returns. /// public partial class Relayer : Arc { public string Log = ""; private void Step(ArcTests.Gates gates, string gate) { int spins = 0; step: while (!gates.Open.Contains(gate)) { ++spins; Yield(); } Log += "step" + spins + ";"; } private void Inner(ArcTests.Gates gates, Y item, string gate) { Y deep = item; inner: while (!gates.Open.Contains(gate)) { Yield(); } Log += "inner" + deep + ";"; } private void Outer(ArcTests.Gates gates, X item) { X held = item; first: Step(gates, "a"); second: Inner(gates, held, "b"); third: Inner(gates, "word", "c"); fourth: Step(gates, "d"); } protected override void Run(ArcTests.Gates gates) { start: Outer(gates, 5); end: Step(gates, "e"); } } /// /// Pauses in a generic passage that does nothing while it waits, so a test can count what pausing allocates. /// public partial class SteadyHolder : Arc { public int Spins; private void Hold(ArcTests.Gates gates, X item) { X held = item; hold: while (!gates.Open.Contains("go")) { ++Spins; Yield(); } Spins += held.GetHashCode(); } protected override void Run(ArcTests.Gates gates) { first: Hold(gates, 7); } } /// /// Calls a generic passage with a constraint, which hands a value back. /// public partial class Chooser : Arc { public int Chosen; public string Said = ""; private Y Choose(ArcTests.Gates gates, X first, Y second) where X : class where Y : struct { X kept = first; Y other = second; choose: while (!gates.Open.Contains("go")) { Yield(); } Said = kept + "/" + other; return other; } protected override void Run(ArcTests.Gates gates) { pick: Chosen = Choose(gates, "left", 41) + 1; } } /// /// Offers generic passages for other arcs to run, one of which calls an ordinary passage of its own arc. /// public partial class Greenhouse : Arc { public int Grown; public string Note = ""; private void Step(ArcTests.Gates gates, string gate) { int spins = 0; step: while (!gates.Open.Contains(gate)) { ++spins; Yield(); } Note += "step" + spins + ";"; } public void Grow(ArcTests.Gates gates, X seed, string gate) { X kept = seed; grow: Step(gates, "s"); wait: while (!gates.Open.Contains(gate)) { Yield(); } Note += "grew" + kept + ";"; ++Grown; } protected override void Run(ArcTests.Gates gates) { } } /// /// Runs a generic passage of another arc with two type arguments. /// public partial class Farmer : Arc { public Greenhouse House; protected override void Run(ArcTests.Gates gates) { first: House.Grow(gates, 4, "g1"); second: House.Grow(gates, "x", "g2"); } } /// /// Passes a variable by ref and another by out to a generic passage, which pauses before it assigns them. /// public partial class Swapper : Arc { public int Left = 1; public int Right; public int Total; private void Swap(ArcTests.Gates gates, ref X left, out X right, X start) { X first = start; right = left; wait: while (!gates.Open.Contains("go")) { Yield(); } right = first; left = first; } protected override void Run(ArcTests.Gates gates) { swap: Swap(gates, ref Left, out Right, 5); Total = Left + Right; } } /// /// Holds a generic passage in a base class that has a type parameter of its own. /// public abstract partial class GenericSteps : Arc { public T Last; public string Log = ""; protected void Hold(ArcTests.Gates gates, T tag, X item) { T kept = tag; X carried = item; hold: while (!gates.Open.Contains("go")) { Yield(); } Last = kept; Log += carried + ";"; } } public partial class IntSteps : GenericSteps { protected override void Run(ArcTests.Gates gates) { first: Hold(gates, 3, "a"); second: Hold(gates, 4, 7L); } } }