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