Files
incremental-game-engine/src/engine/saveLoad.ts
T

80 lines
2.3 KiB
TypeScript

import { defaultGame } from "../prefabs/game";
import { Game, SerializedGame, SerializedNodeBehaviour } from "../types";
import { Behaviour, behaviours, Converter } from "./functions";
export function serializeBehaviour(behaviour: Behaviour): SerializedNodeBehaviour {
switch (behaviour.kind) {
case 'converter': {
const converter = behaviour as Converter;
return {
id: converter.id,
kind: 'converter',
inputs: {
pins: converter.inputs.pins.map((pin) => ({
...pin,
rate: converter.inputRates[pin.resource] ?? 0,
})),
},
outputs: {
pins: converter.outputs.pins.map((pin) => ({
...pin,
rate: converter.outputRates[pin.resource] ?? 0,
})),
},
};
}
default:
throw new Error('Unknown behaviour');
}
}
export function deserializeBehaviour(value: SerializedNodeBehaviour): Behaviour {
switch (value.kind) {
case 'converter':
return new (behaviours.converter)(value);
default:
throw new Error('Unknown behaviour');
}
}
export function serialize(game: Game): SerializedGame {
return {
time: game.time,
nodes: game.nodes.map((node) => ({
id: node.id,
name: node.name,
behaviour: serializeBehaviour(node.behaviour),
})),
};
}
export function deserialize(value: SerializedGame): Game {
return new Game(value);
}
export function serializeToString(game: Game): string {
return JSON.stringify(serialize(game));
}
export function deserializeFromString(value: string): Game {
return deserialize(JSON.parse(value));
}
const KEY_GAME = 'incgane';
export function save(game: Game) {
localStorage.setItem(KEY_GAME, serializeToString(game));
}
export function load(): Game {
try {
const raw = localStorage.getItem(KEY_GAME);
if (raw)
return deserializeFromString(raw);
} catch (e) {
console.warn('Не удалось прочитать игру из localStorage', e);
}
const fresh = deserialize(defaultGame());
save(fresh);
return fresh;
}