HumanBreak/packages/legacy-system/src/storage.ts

117 lines
2.6 KiB
TypeScript

import { isNil } from 'lodash-es';
export class GameStorage<T extends object = any> {
static list: GameStorage<any>[] = [];
key: string;
data!: Partial<T>;
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<K extends keyof T>(key: K, value: T[K]): void;
setValue(key: string, value: any): void;
setValue<K extends keyof T>(key: K, value: T[K]) {
this.data[key] = value;
}
getValue<K extends keyof T>(key: K): T[K] | null;
getValue<K extends keyof T>(key: K, defaults: T[K]): T[K];
getValue<T>(key: string, defaults?: T): T;
getValue<K extends keyof T>(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());
});