Add autosave, make saving a bit less weird
This commit is contained in:
parent
53aebd4c50
commit
755ae037a9
3 changed files with 45 additions and 22 deletions
|
@ -3,6 +3,7 @@ import type { SharkGame } from "./SharkGame";
|
|||
import { StaticClass } from "./StaticClass";
|
||||
import type { TabHandler } from "./TabHandler";
|
||||
import { LZString } from "./LZString";
|
||||
import { Settings } from "./Settings";
|
||||
|
||||
const __EMPTY_OBJECT = {};
|
||||
type Version0Save = typeof __EMPTY_OBJECT;
|
||||
|
@ -13,7 +14,7 @@ type Version1Save = Version0Save & {
|
|||
type: MessageType;
|
||||
}[];
|
||||
selectedTab: keyof typeof TabHandler["AllTabs"];
|
||||
settings: Record<`${string};${string}`, unknown>;
|
||||
settings: Record<string, Record<string, unknown>>;
|
||||
};
|
||||
|
||||
type CurrentVersionSave = Version1Save;
|
||||
|
@ -22,7 +23,22 @@ type Save = Version0Save | Version1Save;
|
|||
export class SaveHandler extends StaticClass {
|
||||
static readonly saveName = "sharg-save";
|
||||
|
||||
static #saveInterval: ReturnType<typeof setInterval> | undefined = undefined;
|
||||
|
||||
static init(game: typeof SharkGame): void {
|
||||
Settings.settings.subscribe((settings) => {
|
||||
if (SaveHandler.#saveInterval !== undefined) {
|
||||
clearInterval(SaveHandler.#saveInterval);
|
||||
}
|
||||
if (settings.behavior.autoSave.current !== "Off") {
|
||||
SaveHandler.#saveInterval = setInterval(() => game.save(), settings.behavior.autoSave.current * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async save(game: typeof SharkGame): Promise<void> {
|
||||
console.debug("Saving");
|
||||
console.time("Done saving");
|
||||
const messages = await new Promise<Message[]>((resolve) => {
|
||||
game.Log.messages.subscribe((messages) => {
|
||||
resolve(messages);
|
||||
|
@ -36,14 +52,17 @@ export class SaveHandler extends StaticClass {
|
|||
const selectedTabIndex = allTabsEntries.findIndex(([, tab]) => tab === game.TabHandler.currentTab);
|
||||
const selectedTabName = allTabsEntries[selectedTabIndex][0];
|
||||
|
||||
const currentSettings = game.Settings.getSaveable();
|
||||
const currentSettings = game.Settings.getSettings();
|
||||
const saveSettings: CurrentVersionSave["settings"] = {};
|
||||
for (const [settingId, setting] of Object.entries(currentSettings) as [
|
||||
keyof typeof currentSettings,
|
||||
typeof currentSettings[keyof typeof currentSettings]
|
||||
][]) {
|
||||
if (setting.current !== setting.default) {
|
||||
saveSettings[settingId] = setting.current;
|
||||
for (const [categoryId, categorySettings] of Object.entries(currentSettings)) {
|
||||
const categorySave: CurrentVersionSave["settings"][string] = {};
|
||||
for (const [settingId, setting] of Object.entries(categorySettings)) {
|
||||
if (setting.current !== setting.default) {
|
||||
categorySave[settingId] = setting.current;
|
||||
}
|
||||
}
|
||||
if (Object.keys(categorySave).length > 0) {
|
||||
saveSettings[categoryId] = categorySave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +84,7 @@ export class SaveHandler extends StaticClass {
|
|||
Math.round((encodedSave.length / stringifiedSave.length) * 100 * 100) / 100
|
||||
}% size`
|
||||
);
|
||||
console.timeEnd("Done saving");
|
||||
|
||||
localStorage.setItem(SaveHandler.saveName, encodedSave);
|
||||
}
|
||||
|
@ -90,8 +110,8 @@ export class SaveHandler extends StaticClass {
|
|||
|
||||
game.Settings.settings.update((settings) => {
|
||||
Object.entries(settings).forEach(([categoryName, categorySettings]) => {
|
||||
Object.entries(categorySettings).forEach(([settingName, setting]) => {
|
||||
setting.current = fullSave.settings[`${categoryName};${settingName}`] ?? setting.default;
|
||||
Object.entries(categorySettings).forEach(([settingId, setting]) => {
|
||||
setting.current = fullSave.settings[categoryName]?.[settingId] ?? setting.default;
|
||||
});
|
||||
});
|
||||
return settings;
|
||||
|
|
|
@ -38,22 +38,21 @@ export class Settings extends StaticClass {
|
|||
options: [true, false] as const,
|
||||
},
|
||||
},
|
||||
behavior: {
|
||||
autoSave: {
|
||||
current: 1 as "Off" | number,
|
||||
default: 1 as const,
|
||||
name: "Autosave" as const,
|
||||
description: "How many seconds to wait between each autosave" as const,
|
||||
options: ["Off", 1, 5, 15, 60] as const,
|
||||
},
|
||||
},
|
||||
};
|
||||
static readonly settings = writable(Settings.#settings);
|
||||
|
||||
static getSettings(): SettingsRecord {
|
||||
return Object.seal(Object.assign({}, Settings.#settings));
|
||||
}
|
||||
static getSaveable(): Record<`${string};${string}`, Setting> {
|
||||
const current = this.getSettings();
|
||||
const result: Record<`${string};${string}`, Setting> = {};
|
||||
for (const [categoryName, category] of Object.entries(current)) {
|
||||
for (const [settingName, setting] of Object.entries(category)) {
|
||||
result[`${categoryName};${settingName}`] = setting;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export type Setting = {
|
||||
|
|
|
@ -68,12 +68,16 @@ export class SharkGame extends StaticClass {
|
|||
});
|
||||
|
||||
static init(): void {
|
||||
Log.init();
|
||||
|
||||
SaveHandler.load(this);
|
||||
|
||||
Log.init();
|
||||
SaveHandler.init(this);
|
||||
|
||||
SharkGame.title = SharkGame.#GAME_NAMES[Math.floor(Math.random() * SharkGame.#GAME_NAMES.length)];
|
||||
}
|
||||
static save(): void {
|
||||
SaveHandler.save(this);
|
||||
}
|
||||
}
|
||||
|
||||
window.SharkGame = SharkGame;
|
||||
|
|
Reference in a new issue