nodes/save_io.pyΒΆ
Part of GDQuest Open RPG.
1"""JSON save / load for the save shrine."""
2
3from __future__ import annotations
4
5import json
6import os
7from pathlib import Path
8from typing import Any
9
10_SAVE_DIR_NAME = "saves"
11_SAVE_FILE_NAME = "open_rpg.json"
12
13
14class SaveStore:
15 """Atomic JSON save with one rotated .bak."""
16
17 def __init__(self, path: Path | None = None) -> None:
18 if path is None:
19 base = Path.cwd() / _SAVE_DIR_NAME
20 path = base / _SAVE_FILE_NAME
21 self.path = path
22
23 def save(self, data: dict[str, Any]) -> None:
24 try:
25 self.path.parent.mkdir(parents=True, exist_ok=True)
26 tmp = self.path.with_suffix(".tmp")
27 tmp.write_text(json.dumps(data, indent=2))
28 if self.path.exists():
29 bak = self.path.with_suffix(".bak")
30 if bak.exists():
31 bak.unlink()
32 os.replace(self.path, bak)
33 os.replace(tmp, self.path)
34 except OSError:
35 pass
36
37 def load(self) -> dict[str, Any] | None:
38 try:
39 if not self.path.exists():
40 return None
41 return json.loads(self.path.read_text())
42 except (OSError, json.JSONDecodeError):
43 return None