isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
73 lines (72 loc) • 3.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadFromDisk = loadFromDisk;
const jsonHelpers_1 = require("../../../../functions/jsonHelpers");
const log_1 = require("../../../../functions/log");
const merge_1 = require("../../../../functions/merge");
const table_1 = require("../../../../functions/table");
const types_1 = require("../../../../functions/types");
const constants_1 = require("./constants");
const DEFAULT_MOD_DATA = "{}";
function loadFromDisk(mod, oldSaveData, classConstructors) {
if (!mod.HasData()) {
// There is no "save#.dat" file for this save slot.
return;
}
// First, read the "save#.dat" file into a Lua table.
const jsonString = readSaveDatFile(mod);
const newSaveData = (0, jsonHelpers_1.jsonDecode)(jsonString);
if (newSaveData === undefined) {
// Reading the save data failed.
return;
}
if (constants_1.SAVE_DATA_MANAGER_DEBUG) {
(0, log_1.log)('Converted data from the "save#.dat" to a Lua table.');
}
// Second, iterate over all the fields of the new table.)
(0, table_1.iterateTableInOrder)(newSaveData, (subscriberName, saveData) => {
// All elements of loaded save data should have keys that are strings equal to the name of the
// subscriber/feature. Ignore elements with other types of keys.
if (!(0, types_1.isString)(subscriberName)) {
return;
}
// All elements of loaded save data should be tables that contain fields corresponding to the
// `SaveData` interface. Ignore elements that are not tables.
if (!(0, types_1.isTable)(saveData)) {
return;
}
// Ignore elements that represent subscriptions that no longer exist in the current save data.
const oldSaveDataForSubscriber = oldSaveData.get(subscriberName);
if (oldSaveDataForSubscriber === undefined) {
return;
}
if (constants_1.SAVE_DATA_MANAGER_DEBUG) {
(0, log_1.log)(`Merging in stored data for feature: ${subscriberName}`);
}
// We do not want to blow away the child tables of the existing map, because save data could
// contain out-of-date fields. Instead, merge it one field at a time in a recursive way (and
// convert Lua tables back to TypeScriptToLua Maps, if necessary).
(0, merge_1.merge)(oldSaveDataForSubscriber, saveData, subscriberName, classConstructors);
}, constants_1.SAVE_DATA_MANAGER_DEBUG);
(0, log_1.log)(`The save data manager loaded data from the "save#.dat" file for mod: ${mod.Name}`);
}
function readSaveDatFile(mod) {
const renderFrameCount = Isaac.GetFrameCount();
const [ok, jsonStringOrErrMsg] = pcall(tryLoadModData, mod);
if (!ok) {
(0, log_1.logError)(`Failed to read from the "save#.dat" file on render frame ${renderFrameCount}: ${jsonStringOrErrMsg}`);
return DEFAULT_MOD_DATA;
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (jsonStringOrErrMsg === undefined) {
return DEFAULT_MOD_DATA;
}
const jsonStringTrimmed = jsonStringOrErrMsg.trim();
if (jsonStringTrimmed === "") {
return DEFAULT_MOD_DATA;
}
return jsonStringTrimmed;
}
function tryLoadModData(mod) {
return mod.LoadData();
}