using System.IO; using Vellum; namespace Annulus.Vellum { /// /// Saves a HexGrid as its shape, what lies outside it, and its cells in the order of the grid. /// public sealed class HexGridConverter<[Saveable] CellType> : SaveConverter> { public const string OrientationKey = "orientation"; public const string RowsKey = "rows"; public const string ColumnsKey = "columns"; public const string OutOfBoundsKey = "outOfBounds"; public const string CellsKey = "cells"; public override SaveNode Write(HexGrid value, SaveSession session) { var cells = new CellType[value.Count]; for (int i = 0; i < cells.Length; ++i) { cells[i] = value[value.IndexAt(i)]; } SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[OrientationKey] = session.ToNode(value.Orientation); returnMe.Entries[RowsKey] = session.ToNode(value.Rows); returnMe.Entries[ColumnsKey] = session.ToNode(value.Columns); returnMe.Entries[OutOfBoundsKey] = session.ToNode(value.OutOfBounds); returnMe.Entries[CellsKey] = SavedItems.ToNode(cells, session); return returnMe; } public override HexGrid Read(SaveNode node, SaveSession session) { var reader = new SaveReader(node, session); HexOrientation orientation = reader.Require(OrientationKey); int rows = reader.Require(RowsKey); int columns = reader.Require(ColumnsKey); CellType outOfBounds = reader.Require(OutOfBoundsKey); CellType[] cells = SavedItems.FromNode(node.RequireEntry(CellsKey), session); // Compared before anything is allocated, so a damaged shape can't ask for a huge grid. if (rows < 0 || columns < 0 || (long)rows * columns != cells.Length) { throw new InvalidDataException("A saved grid of " + rows + " rows and " + columns + " columns holds " + cells.Length + " cells."); } var returnMe = new HexGrid(orientation, rows, columns, outOfBounds); for (int i = 0; i < cells.Length; ++i) { returnMe[returnMe.IndexAt(i)] = cells[i]; } return returnMe; } public override bool TryListChildren(SaveNode node, ChildList children) { SaveNode outOfBounds; SaveNode cells; if (!node.TryGetEntry(OutOfBoundsKey, out outOfBounds) || !node.TryGetEntry(CellsKey, out cells)) { return false; } children.Add(outOfBounds, typeof(CellType)); return SavedItems.ListChildren(cells, typeof(CellType), children); } } }