namespace Ariadne.UnitTests { /// /// Greets from a virtual passage that a derived class overrides, from a Run that only the base writes. /// public abstract partial class Greeter : Arc { public string Log = ""; protected virtual void Greet(ArcTests.Gates gates) { string word = "hello"; hello: while (!gates.Open.Contains("hello")) { Yield(); } Log += word + ";"; } protected override void Run(ArcTests.Gates gates) { Greet(gates); Log += "done;"; } } /// /// Takes the greeting from its base. /// public partial class PlainGreeter : Greeter { } /// /// Overrides the greeting with one that keeps a local of its own across the pause. /// public partial class LoudGreeter : Greeter { protected override void Greet(ArcTests.Gates gates) { int volume = 3; shout: while (!gates.Open.Contains("shout")) { Yield(); } Log += "LOUD" + volume + ";"; } } /// /// Overrides an override, and is itself the base of another override. /// public partial class LoudestGreeter : LoudGreeter { protected override void Greet(ArcTests.Gates gates) { string volume = "max"; bellow: while (!gates.Open.Contains("bellow")) { Yield(); } Log += "LOUDEST " + volume + ";"; } } /// /// Runs the greeting it overrides between two pauses of its own, with a local named like the base's of another /// type. /// public partial class Escalator : Greeter { protected override void Greet(ArcTests.Gates gates) { int word = 5; before: while (!gates.Open.Contains("before")) { Yield(); } base.Greet(gates); Log += "after " + word + ";"; } } /// /// Overrides a virtual passage with a body that never pauses. /// public partial class SilentGreeter : Greeter { protected override void Greet(ArcTests.Gates gates) { Log += "silence;"; } } /// /// Returns a value from a virtual passage. /// public abstract partial class Appraiser : Arc { public int Total; protected virtual int Cost(ArcTests.Gates gates, int quantity) { return quantity; } protected override void Run(ArcTests.Gates gates) { one: int first = Cost(gates, 2); two: int second = Cost(gates, 3); Total = first * 100 + second; } } /// /// Takes the appraisal from its base. /// public partial class PlainAppraiser : Appraiser { } /// /// Appraises at a flat price, after waiting for a gate. /// public partial class Haggler : Appraiser { protected override int Cost(ArcTests.Gates gates, int quantity) { int price = 10; haggle: while (!gates.Open.Contains("haggle" + quantity)) { Yield(); } return price * quantity; } } /// /// Calls a passage that it leaves to the classes that derive from it. /// public abstract partial class Merchant : Arc { public string Log = ""; protected abstract void Barter(ArcTests.Gates gates, int offer); protected override void Run(ArcTests.Gates gates) { Barter(gates, 7); Log += "closed;"; } } /// /// Asks double, and keeps what it asked across the pause. /// public partial class Stubborn : Merchant { protected override void Barter(ArcTests.Gates gates, int offer) { int asked = offer * 2; deal: while (!gates.Open.Contains("deal")) { Yield(); } Log += "asked " + asked + ";"; } } /// /// Goes down three levels with a passage of its own, calling a virtual hook at each. /// public abstract partial class Surveyor : Arc { public string Log = ""; protected abstract void Inspect(ArcTests.Gates gates, int depth); private void Descend(ArcTests.Gates gates, int depth) { inspect: Inspect(gates, depth); if (depth < 2) { deeper: Descend(gates, depth + 1); } } protected override void Run(ArcTests.Gates gates) { start: Descend(gates, 0); } } /// /// Pauses in the hook at each level, with a local across the pause. /// public partial class PausingSurveyor : Surveyor { protected override void Inspect(ArcTests.Gates gates, int depth) { int seen = depth * 10; look: while (!gates.Open.Contains("look" + depth)) { Yield(); } Log += seen + ";"; } } /// /// Visits through a virtual passage that calls on to another, which the base doesn't know the override of. /// public abstract partial class Walker : Arc { public string Log = ""; protected virtual void Next(ArcTests.Gates gates) { } protected virtual void Visit(ArcTests.Gates gates) { Log += "visit;"; Next(gates); } protected override void Run(ArcTests.Gates gates) { Visit(gates); } } /// /// Takes the walk from its base, which goes nowhere. /// public partial class PlainWalker : Walker { } /// /// Walks on from Next back into Visit, so Visit runs again before it has finished. /// public partial class LoopingWalker : Walker { protected override void Next(ArcTests.Gates gates) { Visit(gates); } } }