namespace Vellum.UnitTests { /// /// A type that can contain itself, whose converter lists the part it loads, to drive loading deep chains. /// public class Bead { public Bead Next; } public class BeadConverter : SaveConverter { public override SaveNode Write(Bead value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["next"] = session.ToNode(value.Next, typeof(Bead)); return returnMe; } public override Bead Read(SaveNode node, SaveSession session) { return new Bead { Next = session.FromNode(node.RequireEntry("next")) }; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode next; if (!node.TryGetEntry("next", out next)) { return false; } children.Add(next, typeof(Bead)); return true; } } /// /// A type that holds a bead, whose converter requires it through a reader, to drive failures of parts that the load /// read ahead. /// public class Carrier { public Bead Load; } public class CarrierConverter : SaveConverter { public override SaveNode Write(Carrier value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["load"] = session.ToNode(value.Load, typeof(Bead)); return returnMe; } public override Carrier Read(SaveNode node, SaveSession session) { return new Carrier { Load = new SaveReader(node, session).Require("load") }; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode load; if (!node.TryGetEntry("load", out load)) { return false; } children.Add(load, typeof(Bead)); return true; } } /// /// A struct that holds a bead, to drive a chain that goes through a value type. /// public struct BeadHolder { public Bead Head; } public class BeadHolderConverter : SaveConverter { public override SaveNode Write(BeadHolder value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["head"] = session.ToNode(value.Head, typeof(Bead)); return returnMe; } public override BeadHolder Read(SaveNode node, SaveSession session) { return new BeadHolder { Head = session.FromNode(node.RequireEntry("head")) }; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode head; if (!node.TryGetEntry("head", out head)) { return false; } children.Add(head, typeof(Bead)); return true; } } /// /// A struct whose converter lists a part of its own type, which a hand-made save can make point back at itself. /// public struct Coil { public int Turns; } public class CoilConverter : SaveConverter { public override SaveNode Write(Coil value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["turns"] = session.ToNode(value.Turns); return returnMe; } public override Coil Read(SaveNode node, SaveSession session) { return new Coil { Turns = session.FromNode(node.RequireEntry("turns")) }; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode inner; if (!node.TryGetEntry("inner", out inner)) { return false; } children.Add(inner, typeof(Coil)); return true; } } public interface IPouch { } /// /// A struct that holds another behind an interface, so a chain of them is a chain of boxed values. /// public struct Satchel : IPouch { public IPouch Inner; } public class SatchelConverter : SaveConverter { public override SaveNode Write(Satchel value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["inner"] = session.ToNode(value.Inner, typeof(IPouch)); return returnMe; } public override Satchel Read(SaveNode node, SaveSession session) { return new Satchel { Inner = (IPouch)session.FromNode(node.RequireEntry("inner"), typeof(IPouch)) }; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode inner; if (!node.TryGetEntry("inner", out inner)) { return false; } children.Add(inner, typeof(IPouch)); return true; } } }