import { isNil } from 'lodash-es'; export class GameStorage { static list: GameStorage[] = []; key: string; data!: Partial; constructor(key: string) { this.key = key; this.read(); GameStorage.list.push(this); } /** * 从本地存储读取 */ read(): T { const data = localStorage.getItem(this.key) ?? '{}'; return (this.data = JSON.parse(data)); } /** * 写入本地存储 */ write() { localStorage.setItem(this.key, JSON.stringify(this.data)); } /** * 设置存储的值 * @param key 存储的名称 * @param value 存储的值 */ setValue(key: K, value: T[K]): void; setValue(key: string, value: any): void; setValue(key: K, value: T[K]) { this.data[key] = value; } getValue(key: K): T[K] | null; getValue(key: K, defaults: T[K]): T[K]; getValue(key: string, defaults?: T): T; getValue(key: K, defaults?: T[K]) { if (!isNil(this.data[key])) return this.data[key]; else { if (defaults !== void 0) { this.data[key] = defaults; return defaults; } return null; } } toJSON() { return JSON.stringify(this.data); } clear() { this.data = {}; } keys() { return Object.keys(this.data); } values() { return Object.values(this.data); } entries() { return Object.entries(this.data); } /** * 获取本游戏的存储键 * @param key 存储名称 */ static fromGame(key: string) { return `HumanBreak_${key}`; } /** * 获取与作者相关联的存储键 * @param author 作者名称 * @param key 存储名称 */ static fromAuthor(author: string, key: string) { return `${author}@${key}`; } /** * 根据存储键获取对应的存储实例 * @param key 存储键 * @example Storage.get(Storage.fromAuthor('AncTe', 'setting')); */ static get(key: string) { return this.list.find(v => v.key === key); } /** * 与Symbol.for类似 */ static for(key: string) { const s = this.get(key); if (s) return s; else return new GameStorage(key); } } window.addEventListener('beforeunload', () => { GameStorage.list.forEach(v => v.write()); }); window.addEventListener('blur', () => { GameStorage.list.forEach(v => v.write()); });