Add autosave, make saving a bit less weird

This commit is contained in:
Tobias Berger 2021-10-02 19:17:59 +02:00
parent 53aebd4c50
commit 755ae037a9
3 changed files with 45 additions and 22 deletions

View file

@ -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]
][]) {
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) {
saveSettings[settingId] = setting.current;
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;

View file

@ -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 = {

View file

@ -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;