Put all user settings persistence code in its own module.

This commit is contained in:
Daan Vanden Bosch 2019-07-24 14:31:49 +02:00
parent 3fd812012a
commit ed41a2398b
5 changed files with 144 additions and 101 deletions

View File

@ -0,0 +1,38 @@
import { Persister } from "./Persister";
import { Server, HuntMethod } from "../domain";
class HuntMethodPersister extends Persister {
persist_method_user_times(hunt_methods: HuntMethod[], server: Server): void {
const user_times: PersistedUserTimes = {};
for (const method of hunt_methods) {
if (method.user_time != undefined) {
user_times[method.id] = method.user_time;
}
}
this.persist_for_server(server, "HuntMethodStore.methodUserTimes", user_times);
}
async load_method_user_times(
hunt_methods: HuntMethod[],
server: Server
): Promise<HuntMethod[]> {
const user_times = await this.load_for_server<PersistedUserTimes>(
server,
"HuntMethodStore.methodUserTimes"
);
if (user_times) {
for (const method of hunt_methods) {
method.user_time = user_times[method.id];
}
}
return hunt_methods;
}
}
type PersistedUserTimes = { [method_id: string]: number };
export const hunt_method_persister = new HuntMethodPersister();

View File

@ -0,0 +1,52 @@
import { Server } from "../domain";
import { WantedItem } from "../stores/HuntOptimizerStore";
import { item_type_stores } from "../stores/ItemTypeStore";
import { Persister } from "./Persister";
class HuntOptimizerPersister extends Persister {
persist_wanted_items(server: Server, wanted_items: WantedItem[]): void {
this.persist_for_server(
server,
"HuntOptimizerStore.wantedItems",
wanted_items.map(
({ item_type, amount }): PersistedWantedItem => ({
itemTypeId: item_type.id,
amount,
})
)
);
}
async load_wanted_items(server: Server): Promise<WantedItem[]> {
const item_store = await item_type_stores.get(server).promise;
const persisted_wanted_items = await this.load_for_server<PersistedWantedItem[]>(
server,
"HuntOptimizerStore.wantedItems"
);
const wanted_items: WantedItem[] = [];
if (persisted_wanted_items) {
for (const { itemTypeId, itemKindId, amount } of persisted_wanted_items) {
const item =
itemTypeId != undefined
? item_store.get_by_id(itemTypeId)
: item_store.get_by_id(itemKindId!);
if (item) {
wanted_items.push(new WantedItem(item, amount));
}
}
}
return wanted_items;
}
}
type PersistedWantedItem = {
itemTypeId?: number; // Should only be undefined if the legacy name is still used.
itemKindId?: number; // Legacy name, not persisted, only checked when loading.
amount: number;
};
export const hunt_optimizer_persister = new HuntOptimizerPersister();

View File

@ -0,0 +1,32 @@
import Logger from "js-logger";
import { Server } from "../domain";
const logger = Logger.get("persistence/Persister");
export abstract class Persister {
protected persist_for_server(server: Server, key: string, data: any): void {
this.persist(key + "." + Server[server], data);
}
protected persist(key: string, data: any): void {
try {
localStorage.setItem(key, JSON.stringify(data));
} catch (e) {
logger.error(`Couldn't persist ${key}.`, e);
}
}
protected async load_for_server<T>(server: Server, key: string): Promise<T | undefined> {
return this.load(key + "." + Server[server]);
}
protected async load<T>(key: string): Promise<T | undefined> {
try {
const json = localStorage.getItem(key);
return json && JSON.parse(json);
} catch (e) {
logger.error(`Couldn't load ${key}.`, e);
return undefined;
}
}
}

View File

@ -3,6 +3,7 @@ import { autorun, IReactionDisposer, observable } from "mobx";
import { HuntMethod, NpcType, Server, SimpleQuest } from "../domain";
import { QuestDto } from "../dto";
import { Loadable } from "../Loadable";
import { hunt_method_persister } from "../persistence/HuntMethodPersister";
import { ServerMap } from "./ServerMap";
const logger = Logger.get("stores/HuntMethodStore");
@ -63,54 +64,23 @@ class HuntMethodStore {
);
}
this.load_from_local_storage(methods, server);
await this.load_user_times(methods, server);
return methods;
}
private load_from_local_storage = (methods: HuntMethod[], server: Server) => {
try {
const method_user_times_json = localStorage.getItem(
`HuntMethodStore.methodUserTimes.${Server[server]}`
);
private load_user_times = async (methods: HuntMethod[], server: Server) => {
await hunt_method_persister.load_method_user_times(methods, server);
if (method_user_times_json) {
const user_times: StoredUserTimes = JSON.parse(method_user_times_json);
for (const method of methods) {
method.user_time = user_times[method.id];
}
}
if (this.storage_disposer) {
this.storage_disposer();
}
this.storage_disposer = autorun(() => this.store_in_local_storage(methods, server));
} catch (e) {
logger.error(e);
if (this.storage_disposer) {
this.storage_disposer();
}
this.storage_disposer = autorun(() => this.persist_user_times(methods, server));
};
private store_in_local_storage = (methods: HuntMethod[], server: Server) => {
try {
const user_times: StoredUserTimes = {};
for (const method of methods) {
if (method.user_time != undefined) {
user_times[method.id] = method.user_time;
}
}
localStorage.setItem(
`HuntMethodStore.methodUserTimes.${Server[server]}`,
JSON.stringify(user_times)
);
} catch (e) {
logger.error(e);
}
private persist_user_times = (methods: HuntMethod[], server: Server) => {
hunt_method_persister.persist_method_user_times(methods, server);
};
}
type StoredUserTimes = { [method_id: string]: number };
export const hunt_method_store = new HuntMethodStore();

View File

@ -1,8 +1,9 @@
import solver from "javascript-lp-solver";
import { autorun, IObservableArray, observable, computed } from "mobx";
import { autorun, computed, IObservableArray, observable } from "mobx";
import {
Difficulties,
Difficulty,
Episode,
HuntMethod,
ItemType,
KONDRIEU_PROB,
@ -10,16 +11,12 @@ import {
RARE_ENEMY_PROB,
SectionId,
SectionIds,
Server,
Episode,
} from "../domain";
import { hunt_optimizer_persister } from "../persistence/HuntOptimizerPersister";
import { application_store } from "./ApplicationStore";
import { hunt_method_store } from "./HuntMethodStore";
import { item_drop_stores } from "./ItemDropStore";
import { item_type_stores } from "./ItemTypeStore";
import Logger from "js-logger";
const logger = Logger.get("stores/HuntOptimizerStore");
export class WantedItem {
@observable readonly item_type: ItemType;
@ -91,7 +88,7 @@ class HuntOptimizerStore {
@observable result?: OptimalResult;
constructor() {
this.initialize();
this.initialize_persistence();
}
optimize = async () => {
@ -335,64 +332,18 @@ class HuntOptimizerStore {
return name;
}
private initialize = async () => {
try {
await this.load_from_local_storage();
autorun(this.store_in_local_storage);
} catch (e) {
logger.error(e);
}
};
private load_from_local_storage = async () => {
const wanted_items_json = localStorage.getItem(
`HuntOptimizerStore.wantedItems.${Server[application_store.current_server]}`
private initialize_persistence = async () => {
this.wanted_items.replace(
await hunt_optimizer_persister.load_wanted_items(application_store.current_server)
);
if (wanted_items_json) {
const item_store = await item_type_stores.current.promise;
const wi: StoredWantedItem[] = JSON.parse(wanted_items_json);
const wanted_items: WantedItem[] = [];
for (const { itemTypeId, itemKindId, amount } of wi) {
const item =
itemTypeId != undefined
? item_store.get_by_id(itemTypeId)
: item_store.get_by_id(itemKindId!);
if (item) {
wanted_items.push(new WantedItem(item, amount));
}
}
this.wanted_items.replace(wanted_items);
}
};
private store_in_local_storage = () => {
try {
localStorage.setItem(
`HuntOptimizerStore.wantedItems.${Server[application_store.current_server]}`,
JSON.stringify(
this.wanted_items.map(
({ item_type: itemType, amount }): StoredWantedItem => ({
itemTypeId: itemType.id,
amount,
})
)
)
autorun(() => {
hunt_optimizer_persister.persist_wanted_items(
application_store.current_server,
this.wanted_items
);
} catch (e) {
logger.error(e);
}
});
};
}
type StoredWantedItem = {
itemTypeId?: number; // Should only be undefined if the legacy name is still used.
itemKindId?: number; // Legacy name.
amount: number;
};
export const hunt_optimizer_store = new HuntOptimizerStore();