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