using System.Collections.Generic;
namespace Vellum.UnitTests
{
///
/// A [Saveable] node that can point at others in a loop, to drive loops of generated types.
///
[Saveable]
public sealed partial class Ring
{
public string Name;
public Ring Next;
public Ring Prev;
}
///
/// A [Saveable] class with each kind of member that can't be assigned outside a constructor, and a member that
/// only the constructor sets.
///
[Saveable]
public sealed partial class Ledger
{
public readonly string Title;
public readonly List Entries = new List();
public int Plain;
[NoSave]
public string Cache = "built";
public Ledger(string title, int count, string note)
{
Title = title;
Count = count;
Note = note;
}
public int Count { get; }
public string Note { get; private set; }
}
///
/// A [Saveable] class whose own loader reads through the clan it belongs to, which holds it.
///
[Saveable]
public sealed partial class Clan
{
public string Name;
public List Scouts = new List();
}
[Saveable]
public sealed partial class Scout
{
public Clan Clan;
public int Rank;
[NoSave]
public int ClanSize;
public Scout()
{
}
private Scout(SaveReader reader)
: this(reader, default(AutoLoadEveryField))
{
ClanSize = Clan.Scouts.Count;
}
}
///
/// A [Saveable] class that hashes by its name, which a set of its neighbours needs filled in first.
///
[Saveable]
public sealed partial class Planet
{
public string Name;
public HashSet Neighbors = new HashSet();
public override bool Equals(object other)
{
var planet = other as Planet;
return planet != null && planet.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
///
/// A [Saveable] node that holds a hash set of its neighbours, which hash by identity.
///
[Saveable]
public sealed partial class Vertex
{
public string Name;
public HashSet Neighbors = new HashSet();
}
[Saveable]
public sealed partial class Cell
{
public string Name;
public Cell[] Around;
}
///
/// A class that can be made early and completed, but whose converter writes none of its data before the
/// constructor runs.
///
public class Mote
{
public readonly string Name;
public readonly HashSet Near;
public Mote(string name, HashSet near)
{
Name = name;
Near = near;
}
}
public class MoteConverter : SaveConverter
{
public override SaveNode Write(Mote value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["name"] = session.ToNode(value.Name);
returnMe.Entries["near"] = session.ToNode(value.Near, typeof(HashSet));
return returnMe;
}
public override Mote Read(SaveNode node, SaveSession session)
{
return new Mote(session.FromNode(node.RequireEntry("name")),
session.FromNode>(node.RequireEntry("near")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode near;
if (!node.TryGetEntry("near", out near))
{
return false;
}
children.Add(near, typeof(HashSet));
return true;
}
public override void Complete(Mote blank, SaveNode node, SaveSession session)
{
Construct(blank, session.FromNode(node.RequireEntry("name")),
session.FromNode>(node.RequireEntry("near")));
}
}
///
/// An abstract class with a SaveReader constructor, which still can't be made early because it is abstract.
///
public abstract class Blueprint
{
protected Blueprint(SaveReader reader)
{
}
}
public class BlueprintConverter : SaveConverter
{
public override SaveNode Write(Blueprint value, SaveSession session)
{
return SaveNode.NewTable();
}
public override Blueprint Read(SaveNode node, SaveSession session)
{
throw new System.NotSupportedException();
}
}
///
/// A class with every kind of field a FieldWriter has to reach.
///
public class Bucket
{
public readonly object Anything;
public string Plain;
private readonly string secret;
public Bucket(string secret, int size)
{
this.secret = secret;
Size = size;
}
public int Size { get; }
public string Secret
{
get
{
return secret;
}
}
}
///
/// A class whose constructors a ConstructorRunner has to choose between.
///
public class Counted
{
public readonly int Number;
public readonly string Text;
public Counted(int number)
{
Number = number;
Text = "number";
}
public Counted(string text, string other)
{
Text = text + other;
}
public Counted(string text, object other)
{
Text = text + "object";
}
}
///
/// A class whose constructors a null can't pick between.
///
public class Doubtful
{
public readonly string Text;
public Doubtful(string text)
{
Text = "string";
}
public Doubtful(object other)
{
Text = "object";
}
}
///
/// A class with readonly fields whose converter fills them before any constructor runs. The constructor reads
/// the partner's name, which is only there if the partner was filled.
///
public class Spouse
{
public readonly string Name;
public readonly Spouse Partner;
public readonly int PairedLength;
public Spouse(string name, Spouse partner)
{
Name = name;
Partner = partner;
PairedLength = name.Length;
if (partner != null)
{
PairedLength += partner.Name.Length;
}
}
}
public class SpouseConverter : SaveConverter
{
public static readonly FieldWriter NameField =
new FieldWriter(nameof(Spouse.Name));
public static readonly FieldWriter PartnerField =
new FieldWriter(nameof(Spouse.Partner));
public override SaveNode Write(Spouse value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["name"] = session.ToNode(value.Name);
returnMe.Entries["partner"] = session.ToNode(value.Partner, typeof(Spouse));
return returnMe;
}
public override Spouse Read(SaveNode node, SaveSession session)
{
return new Spouse(session.FromNode(node.RequireEntry("name")),
session.FromNode(node.RequireEntry("partner")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode partner;
if (!node.TryGetEntry("partner", out partner))
{
return false;
}
children.Add(partner, typeof(Spouse));
return true;
}
public override void Fill(Spouse blank, SaveNode node, SaveSession session)
{
NameField.Set(blank, session.FromNode(node.RequireEntry("name")));
PartnerField.Set(blank, session.FromNode(node.RequireEntry("partner")));
}
public override void Complete(Spouse blank, SaveNode node, SaveSession session)
{
Construct(blank, session.FromNode(node.RequireEntry("name")),
session.FromNode(node.RequireEntry("partner")));
}
}
///
/// A class whose converter builds it in one go, in a loop with a Plate that can be made early.
///
public class Knob
{
public readonly Plate Plate;
public Knob(Plate plate)
{
Plate = plate;
}
}
public class KnobConverter : SaveConverter
{
public override SaveNode Write(Knob value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["plate"] = session.ToNode(value.Plate, typeof(Plate));
return returnMe;
}
public override Knob Read(SaveNode node, SaveSession session)
{
return new Knob(session.FromNode(node.RequireEntry("plate")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode plate;
if (!node.TryGetEntry("plate", out plate))
{
return false;
}
children.Add(plate, typeof(Plate));
return true;
}
}
public class Plate
{
public readonly Knob Knob;
public readonly string Label;
public Plate(Knob knob, string label)
{
Knob = knob;
Label = label;
}
}
public class PlateConverter : SaveConverter
{
public static readonly FieldWriter KnobField = new FieldWriter(nameof(Plate.Knob));
public static readonly FieldWriter LabelField =
new FieldWriter(nameof(Plate.Label));
public override SaveNode Write(Plate value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["knob"] = session.ToNode(value.Knob, typeof(Knob));
returnMe.Entries["label"] = session.ToNode(value.Label);
return returnMe;
}
public override Plate Read(SaveNode node, SaveSession session)
{
return new Plate(session.FromNode(node.RequireEntry("knob")),
session.FromNode(node.RequireEntry("label")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode knob;
if (!node.TryGetEntry("knob", out knob))
{
return false;
}
children.Add(knob, typeof(Knob));
return true;
}
public override void Fill(Plate blank, SaveNode node, SaveSession session)
{
KnobField.Set(blank, session.FromNode(node.RequireEntry("knob")));
LabelField.Set(blank, session.FromNode(node.RequireEntry("label")));
}
public override void Complete(Plate blank, SaveNode node, SaveSession session)
{
Construct(blank, session.FromNode(node.RequireEntry("knob")),
session.FromNode(node.RequireEntry("label")));
}
}
///
/// Two classes that point at each other and whose converters only build them in one go, so neither can exist
/// before the other.
///
public class Gate
{
public string Name;
public Latch Latch;
}
public class GateConverter : SaveConverter
{
public override SaveNode Write(Gate value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["name"] = session.ToNode(value.Name);
returnMe.Entries["latch"] = session.ToNode(value.Latch, typeof(Latch));
return returnMe;
}
public override Gate Read(SaveNode node, SaveSession session)
{
return new Gate
{
Name = session.FromNode(node.RequireEntry("name")),
Latch = session.FromNode(node.RequireEntry("latch")),
};
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode latch;
if (!node.TryGetEntry("latch", out latch))
{
return false;
}
children.Add(latch, typeof(Latch));
return true;
}
}
public class Latch
{
public string Name;
public Gate Gate;
}
public class LatchConverter : SaveConverter
{
public override SaveNode Write(Latch value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["name"] = session.ToNode(value.Name);
returnMe.Entries["gate"] = session.ToNode(value.Gate, typeof(Gate));
return returnMe;
}
public override Latch Read(SaveNode node, SaveSession session)
{
return new Latch
{
Name = session.FromNode(node.RequireEntry("name")),
Gate = session.FromNode(node.RequireEntry("gate")),
};
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode gate;
if (!node.TryGetEntry("gate", out gate))
{
return false;
}
children.Add(gate, typeof(Gate));
return true;
}
}
///
/// A class that hashes by its name, which its converter fills before any hash set holding it is.
///
public class Badge
{
public readonly string Name;
public readonly Hub Hub;
public Badge(string name, Hub hub)
{
Name = name;
Hub = hub;
}
public override bool Equals(object other)
{
var badge = other as Badge;
return badge != null && badge.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class BadgeConverter : SaveConverter
{
public static readonly FieldWriter NameField =
new FieldWriter(nameof(Badge.Name));
public static readonly FieldWriter HubField = new FieldWriter(nameof(Badge.Hub));
public override SaveNode Write(Badge value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["name"] = session.ToNode(value.Name);
returnMe.Entries["hub"] = session.ToNode(value.Hub, typeof(Hub));
return returnMe;
}
public override Badge Read(SaveNode node, SaveSession session)
{
return new Badge(session.FromNode(node.RequireEntry("name")),
session.FromNode(node.RequireEntry("hub")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode hub;
if (!node.TryGetEntry("hub", out hub))
{
return false;
}
children.Add(hub, typeof(Hub));
return true;
}
public override void Fill(Badge blank, SaveNode node, SaveSession session)
{
NameField.Set(blank, session.FromNode(node.RequireEntry("name")));
HubField.Set(blank, session.FromNode(node.RequireEntry("hub")));
}
public override void Complete(Badge blank, SaveNode node, SaveSession session)
{
Construct(blank, session.FromNode(node.RequireEntry("name")),
session.FromNode(node.RequireEntry("hub")));
}
}
public class Hub
{
public readonly HashSet Badges;
public Hub(HashSet badges)
{
Badges = badges;
}
}
public class HubConverter : SaveConverter
{
public static readonly FieldWriter> BadgesField =
new FieldWriter>(nameof(Hub.Badges));
public override SaveNode Write(Hub value, SaveSession session)
{
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries["badges"] = session.ToNode(value.Badges, typeof(HashSet));
return returnMe;
}
public override Hub Read(SaveNode node, SaveSession session)
{
return new Hub(session.FromNode>(node.RequireEntry("badges")));
}
public override bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode badges;
if (!node.TryGetEntry("badges", out badges))
{
return false;
}
children.Add(badges, typeof(HashSet));
return true;
}
public override void Fill(Hub blank, SaveNode node, SaveSession session)
{
BadgesField.Set(blank, session.FromNode>(node.RequireEntry("badges")));
}
public override void Complete(Hub blank, SaveNode node, SaveSession session)
{
Construct(blank, session.FromNode>(node.RequireEntry("badges")));
}
}
}