REFACTOR: Mitigate cyclic dependency between Jsonable classes (#1792)

This commit is contained in:
catloversg
2024-11-24 06:53:31 +07:00
committed by GitHub
parent 45a6ca6b8e
commit 05da0efc81
23 changed files with 121 additions and 114 deletions
+2 -35
View File
@@ -1,7 +1,6 @@
/* Generic Reviver, toJSON, and fromJSON functions used for saving and loading objects */
import { ObjectValidator, validateObject } from "./Validator";
import { ObjectValidator } from "./Validator";
import { JSONMap, JSONSet } from "../Types/Jsonable";
import { loadActionIdentifier } from "../Bladeburner/utils/loadActionIdentifier";
import { objectAssert } from "./helpers/typeAssertion";
type JsonableClass = (new () => { toJSON: () => IReviverValue }) & {
@@ -14,44 +13,12 @@ export interface IReviverValue<T = unknown> {
data: T;
}
function isReviverValue(value: unknown): value is IReviverValue {
export function isReviverValue(value: unknown): value is IReviverValue {
return (
typeof value === "object" && value !== null && "ctor" in value && typeof value.ctor === "string" && "data" in value
);
}
/**
* A generic "smart reviver" function.
* Looks for object values with a `ctor` property and a `data` property.
* If it finds them, and finds a matching constructor, it hands
* off to that `fromJSON` function, passing in the value. */
export function Reviver(_key: string, value: unknown): any {
if (!isReviverValue(value)) return value;
const ctor = constructorsForReviver[value.ctor];
if (!ctor) {
// Known missing constructors with special handling.
switch (value.ctor) {
case "AllServersMap": // Reviver removed in v0.43.1
case "Industry": // No longer part of save data since v2.3.0
case "Employee": // Entire object removed from game in v2.2.0 (employees abstracted)
case "Company": // Reviver removed in v2.6.1
case "Faction": // Reviver removed in v2.6.1
console.warn(`Legacy load type ${value.ctor} converted to expected format while loading.`);
return value.data;
case "ActionIdentifier": // No longer a class as of v2.6.1
return loadActionIdentifier(value.data);
}
// Missing constructor with no special handling. Throw error.
throw new Error(`Could not locate constructor named ${value.ctor}. If the save data is valid, this is a bug.`);
}
const obj = ctor.fromJSON(value);
if (ctor.validationData !== undefined) {
validateObject(obj, ctor.validationData);
}
return obj;
}
export const constructorsForReviver: Partial<Record<string, JsonableClass>> = { JSONSet, JSONMap };
/**