using System.Collections.Generic; using Vellum; namespace Clave.Vellum { /// /// Saves and loads a list of chords with their priorities and enabled states, the way every chord holder here does. /// public static class SavedChords { private struct Entry { public SavedChord Saved; public SaveNode Formula; public string FormulaText; } private static string TextOf(SaveNode formula) { var terms = new List(formula.Items.Count); foreach (SaveNode term in formula.Items) { terms.Add(term.Text); } return string.Join("\n", terms); } // Highest priority first, then by formula, so the same chords save the same whatever order they were added in. private static int Compare(Entry first, Entry second) { if (first.Saved.Priority != second.Saved.Priority) { return second.Saved.Priority.CompareTo(first.Saved.Priority); } int byFormula = string.CompareOrdinal(first.FormulaText, second.FormulaText); if (byFormula != 0) { return byFormula; } return second.Saved.Enabled.CompareTo(first.Saved.Enabled); } /// /// Returns a table holding the chords as a list, highest priority first and then by formula. A holder with /// more to save adds its own entries to it. /// public static SaveNode Write(IReadOnlyList chords, SaveSession session) { var entries = new List(chords.Count); foreach (SavedChord saved in chords) { SaveNode formula = session.ToNode(saved.Chord, typeof(Chord)); entries.Add(new Entry { Saved = saved, Formula = formula, FormulaText = TextOf(formula) }); } entries.Sort(Compare); SaveNode list = SaveNode.NewList(); foreach (Entry entry in entries) { SaveNode node = SaveNode.NewTable(); node.Entries[ChordSetConverter.ChordKey] = entry.Formula; node.Entries[ChordSetConverter.PriorityKey] = session.ToNode(entry.Saved.Priority); node.Entries[ChordSetConverter.EnabledKey] = session.ToNode(entry.Saved.Enabled); list.Items.Add(node); } SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[ChordSetConverter.ChordsKey] = list; return returnMe; } /// /// Returns the chords of a table that made, in the order saved. A chord with no priority /// has zero, and one with no enabled state is enabled. /// public static List Read(SaveNode node, SaveSession session) { IReadOnlyList saved = node.RequireEntry(ChordSetConverter.ChordsKey).RequireItems(); new SaveReader(node, session).Skip(ChordSetConverter.ChordsKey); var returnMe = new List(saved.Count); for (int i = 0; i < saved.Count; ++i) { var reader = new SaveReader(saved[i], session); Chord chord = reader.Require(ChordSetConverter.ChordKey); int priority; reader.TryRead(ChordSetConverter.PriorityKey, out priority); bool enabled; if (!reader.TryRead(ChordSetConverter.EnabledKey, out enabled)) { enabled = true; } returnMe.Add(new SavedChord(chord, priority, enabled)); } return returnMe; } /// /// Lists the chords of a table that made as children, and returns false if it isn't one. /// public static bool TryListChildren(SaveNode node, ChildList children) { SaveNode chords; IReadOnlyList entries; if (!node.TryGetEntry(ChordSetConverter.ChordsKey, out chords) || !chords.TryGetItems(out entries)) { return false; } foreach (SaveNode entry in entries) { SaveNode chord; if (!entry.TryGetEntry(ChordSetConverter.ChordKey, out chord)) { return false; } children.Add(chord, typeof(Chord)); } return true; } } }