import { Registry } from "./registry.js";
/**
* Abstract base class for piece serializers.
*
* For each piece type there is a serializer that can convert the piece back and
* forth to a key, and that also provides metadata about the type for the map
* editor. Mirrors the Java Serializer<T> interface exactly.
*
* Subclasses must override all five methods.
*/
export class Serializer {
/**
* Reconstruct a piece from its resolved args array.
* String args are plain values; Piece args are already-resolved nested
* registry lookups (the Registry resolves "^"-escaped sub-keys before
* calling create, exactly as it does today).
* @param {Array<string|Piece>} args
* @returns {Piece}
*/
create(_args) {
throw new Error("Serializer.create() not implemented");
}
/**
* Return the canonical serialized key for this piece, e.g. "Door|Blue|off".
* The key must be parseable back via create().
* @param {Piece} piece
* @returns {string}
*/
store(_piece) {
throw new Error("Serializer.store() not implemented");
}
/**
* Return a representative instance of this type for display in the map editor.
* @returns {Piece}
*/
example() {
throw new Error("Serializer.example() not implemented");
}
/**
* Given the typeId, return a human-readable template showing the key format,
* e.g. "Door|{color}|{state}". Used by the editor to guide authoring.
* @param {string} typeId
* @returns {string}
*/
template(_typeId) {
throw new Error("Serializer.template() not implemented");
}
/**
* Return the editor category for this type, e.g. "Terrain", "Room Features".
* @returns {string}
*/
tag() {
throw new Error("Serializer.tag() not implemented");
}
}
// ── TypeOnlySerializer ────────────────────────────────────────────────────────
/**
* A serializer base that works for any piece defined only by its type.
* The key is just the typeId with no arguments (e.g. "Floor", "Wall", "Fire").
* Subclasses implement create() (return a new instance) and tag().
*/
export class TypeOnlySerializer extends Serializer {
/** @param {string} typeId */
constructor(typeId) {
super();
this._typeId = typeId;
}
store(_piece) {
return this._typeId;
}
example() {
return this.create(null);
}
template(_typeId) {
return this._typeId;
}
}
// ── BaseSerializer ────────────────────────────────────────────────────────────
/**
* Base support for serializers that escape/unescape pieces as part of their
* serialization key. Provides esc() and unesc*() helpers for building and
* parsing keys that embed other pieces. Subclasses must implement all five
* Serializer methods.
*/
export class BaseSerializer extends Serializer {
/**
* Escape a piece reference for embedding inside another key.
* Replaces "|" with "^" so the nested key does not break pipe-splitting.
* @param {Piece} piece
* @returns {string}
*/
esc(piece) {
return Registry.serialize(piece).replaceAll("|", "^");
}
/**
* Unescape a terrain reference embedded in a key arg.
* The Registry has already resolved "^"-escaped args into Piece instances
* before calling create(), so this helper is provided only for cases where
* manual resolution is needed outside of create().
* @param {string} key escaped key (carets instead of pipes)
* @returns {Terrain}
*/
unescTerrain(key) {
return Registry.get(key.replaceAll("^", "|"));
}
/** @param {string} key @returns {Item} */
unescItem(key) {
return Registry.get(key.replaceAll("^", "|"));
}
/** @param {string} key @returns {Piece} */
unesc(key) {
return Registry.get(key.replaceAll("^", "|"));
}
}