isaacscript-common 6.9.0 → 6.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/customStage/customStageGridEntities.lua +2 -2
- package/dist/features/customStage/exports.d.ts.map +1 -1
- package/dist/features/customStage/exports.lua +5 -4
- package/dist/features/customStage/init.d.ts.map +1 -1
- package/dist/features/customStage/init.lua +12 -3
- package/dist/features/customStage/streakText.d.ts +4 -2
- package/dist/features/customStage/streakText.d.ts.map +1 -1
- package/dist/features/customStage/streakText.lua +216 -15
- package/dist/features/customStage/v.d.ts +4 -2
- package/dist/features/customStage/v.d.ts.map +1 -1
- package/dist/features/customStage/v.lua +9 -1
- package/dist/features/customStage/versusScreen.d.ts +1 -1
- package/dist/features/customStage/versusScreen.d.ts.map +1 -1
- package/dist/features/customStage/versusScreen.lua +2 -5
- package/dist/features/extraConsoleCommands/init.lua +1 -0
- package/dist/features/extraConsoleCommands/listCommands.d.ts +8 -0
- package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/listCommands.lua +13 -0
- package/dist/features/saveDataManager/exports.d.ts.map +1 -1
- package/dist/features/saveDataManager/exports.lua +2 -4
- package/dist/features/saveDataManager/load.d.ts +1 -1
- package/dist/features/saveDataManager/load.d.ts.map +1 -1
- package/dist/features/saveDataManager/main.d.ts.map +1 -1
- package/dist/features/saveDataManager/main.lua +0 -1
- package/dist/features/saveDataManager/maps.d.ts +3 -3
- package/dist/features/saveDataManager/maps.d.ts.map +1 -1
- package/dist/features/saveDataManager/maps.lua +1 -4
- package/dist/features/saveDataManager/merge.d.ts +2 -2
- package/dist/features/saveDataManager/merge.d.ts.map +1 -1
- package/dist/features/saveDataManager/merge.lua +3 -3
- package/dist/features/saveDataManager/save.d.ts +1 -1
- package/dist/features/saveDataManager/save.d.ts.map +1 -1
- package/dist/features/saveDataManager/save.lua +1 -2
- package/dist/features/saveDataManager/{serializationBrand.d.ts → serializationBrands.d.ts} +1 -1
- package/dist/features/saveDataManager/serializationBrands.d.ts.map +1 -0
- package/dist/features/saveDataManager/{serializationBrand.lua → serializationBrands.lua} +0 -0
- package/dist/functions/array.d.ts.map +1 -1
- package/dist/functions/color.d.ts +1 -1
- package/dist/functions/color.d.ts.map +1 -1
- package/dist/functions/deepCopy.d.ts +1 -1
- package/dist/functions/deepCopy.lua +73 -37
- package/dist/functions/deepCopyTests.d.ts.map +1 -1
- package/dist/functions/deepCopyTests.lua +85 -18
- package/dist/functions/entities.d.ts +1 -1
- package/dist/functions/entities.d.ts.map +1 -1
- package/dist/functions/input.d.ts.map +1 -1
- package/dist/functions/input.lua +8 -10
- package/dist/functions/jsonHelpers.d.ts +1 -1
- package/dist/functions/jsonHelpers.d.ts.map +1 -1
- package/dist/functions/kColor.d.ts +1 -1
- package/dist/functions/kColor.d.ts.map +1 -1
- package/dist/functions/log.d.ts +1 -1
- package/dist/functions/log.d.ts.map +1 -1
- package/dist/functions/log.lua +3 -1
- package/dist/functions/mergeTests.d.ts +2 -2
- package/dist/functions/mergeTests.lua +2 -6
- package/dist/functions/playerIndex.d.ts +1 -1
- package/dist/functions/playerIndex.lua +1 -1
- package/dist/functions/rng.d.ts +1 -1
- package/dist/functions/rng.d.ts.map +1 -1
- package/dist/functions/table.d.ts +9 -9
- package/dist/functions/table.d.ts.map +1 -1
- package/dist/functions/table.lua +23 -21
- package/dist/functions/types.d.ts +1 -1
- package/dist/functions/types.d.ts.map +1 -1
- package/dist/functions/vector.d.ts +1 -1
- package/dist/functions/vector.d.ts.map +1 -1
- package/dist/interfaces/SaveData.d.ts +1 -1
- package/dist/interfaces/private/TSTLClassMetatable.d.ts +1 -1
- package/dist/interfaces/private/TSTLClassMetatable.d.ts.map +1 -1
- package/dist/lualib_bundle.lua +38 -7
- package/dist/types/PlayerIndex.d.ts +3 -2
- package/dist/types/PlayerIndex.d.ts.map +1 -1
- package/dist/types/private/IsaacAPIClass.d.ts +1 -1
- package/dist/types/private/IsaacAPIClass.d.ts.map +1 -1
- package/dist/types/private/SerializedIsaacAPIClass.d.ts +1 -1
- package/dist/types/private/SerializedIsaacAPIClass.d.ts.map +1 -1
- package/dist/types/private/TSTLClass.d.ts +1 -1
- package/dist/types/private/TSTLClass.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/features/customStage/customStageGridEntities.ts +4 -4
- package/src/features/customStage/exports.ts +5 -3
- package/src/features/customStage/init.ts +19 -7
- package/src/features/customStage/streakText.ts +284 -19
- package/src/features/customStage/v.ts +6 -1
- package/src/features/customStage/versusScreen.ts +2 -5
- package/src/features/extraConsoleCommands/init.ts +1 -0
- package/src/features/extraConsoleCommands/listCommands.ts +14 -0
- package/src/features/saveDataManager/exports.ts +3 -8
- package/src/features/saveDataManager/load.ts +2 -3
- package/src/features/saveDataManager/main.ts +4 -5
- package/src/features/saveDataManager/maps.ts +3 -3
- package/src/features/saveDataManager/merge.ts +11 -11
- package/src/features/saveDataManager/save.ts +6 -6
- package/src/features/saveDataManager/{serializationBrand.ts → serializationBrands.ts} +0 -0
- package/src/functions/array.ts +2 -4
- package/src/functions/color.ts +3 -3
- package/src/functions/deepCopy.ts +95 -41
- package/src/functions/deepCopyTests.ts +161 -28
- package/src/functions/entities.ts +7 -7
- package/src/functions/input.ts +7 -8
- package/src/functions/isaacAPIClass.ts +3 -3
- package/src/functions/jsonHelpers.ts +3 -3
- package/src/functions/kColor.ts +3 -3
- package/src/functions/log.ts +7 -4
- package/src/functions/mergeTests.ts +24 -32
- package/src/functions/playerIndex.ts +1 -1
- package/src/functions/rng.ts +3 -3
- package/src/functions/table.ts +25 -23
- package/src/functions/tstlClass.ts +1 -1
- package/src/functions/types.ts +3 -1
- package/src/functions/vector.ts +3 -3
- package/src/interfaces/SaveData.ts +1 -1
- package/src/interfaces/private/TSTLClassMetatable.ts +1 -1
- package/src/types/PlayerIndex.ts +3 -2
- package/src/types/private/IsaacAPIClass.ts +1 -1
- package/src/types/private/SerializedIsaacAPIClass.ts +1 -1
- package/src/types/private/TSTLClass.ts +1 -1
- package/dist/features/saveDataManager/serializationBrand.d.ts.map +0 -1
|
@@ -12,7 +12,7 @@ import { isDefaultMap, isTSTLMap, isTSTLSet } from "../../functions/tstlClass";
|
|
|
12
12
|
import { isTable } from "../../functions/types";
|
|
13
13
|
import { getTraversalDescription } from "../../functions/utils";
|
|
14
14
|
import { SAVE_DATA_MANAGER_DEBUG } from "./saveDataManagerConstants";
|
|
15
|
-
import { isSerializationBrand } from "./
|
|
15
|
+
import { isSerializationBrand } from "./serializationBrands";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* `merge` takes the values from a new table and recursively merges them into an old object (while
|
|
@@ -20,7 +20,7 @@ import { isSerializationBrand } from "./serializationBrand";
|
|
|
20
20
|
*
|
|
21
21
|
* It supports the following object types:
|
|
22
22
|
*
|
|
23
|
-
* -
|
|
23
|
+
* - Basic TSTL objects / tables
|
|
24
24
|
* - TSTL `Map`
|
|
25
25
|
* - TSTL `Set`
|
|
26
26
|
* - TSTL classes
|
|
@@ -38,10 +38,10 @@ import { isSerializationBrand } from "./serializationBrand";
|
|
|
38
38
|
*/
|
|
39
39
|
export function merge(
|
|
40
40
|
oldObject:
|
|
41
|
-
|
|
|
41
|
+
| LuaMap<AnyNotNil, unknown>
|
|
42
42
|
| Map<AnyNotNil, unknown>
|
|
43
43
|
| Set<AnyNotNil>,
|
|
44
|
-
newTable:
|
|
44
|
+
newTable: LuaMap<AnyNotNil, unknown>,
|
|
45
45
|
traversalDescription: string,
|
|
46
46
|
): void {
|
|
47
47
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -73,8 +73,8 @@ export function merge(
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function mergeArray(
|
|
76
|
-
oldArray:
|
|
77
|
-
newArray:
|
|
76
|
+
oldArray: LuaMap<AnyNotNil, unknown>,
|
|
77
|
+
newArray: LuaMap<AnyNotNil, unknown>,
|
|
78
78
|
) {
|
|
79
79
|
// Assume that we should blow away all array values with whatever is present in the incoming
|
|
80
80
|
// array.
|
|
@@ -90,7 +90,7 @@ function mergeArray(
|
|
|
90
90
|
|
|
91
91
|
function mergeTSTLObject(
|
|
92
92
|
oldObject: Map<AnyNotNil, unknown> | Set<AnyNotNil>,
|
|
93
|
-
newTable:
|
|
93
|
+
newTable: LuaMap<AnyNotNil, unknown>,
|
|
94
94
|
traversalDescription: string,
|
|
95
95
|
) {
|
|
96
96
|
// We blow away the old object and recursively copy over all of the incoming values.
|
|
@@ -140,8 +140,8 @@ function mergeTSTLObject(
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
function mergeTable(
|
|
143
|
-
oldTable:
|
|
144
|
-
newTable:
|
|
143
|
+
oldTable: LuaMap<AnyNotNil, unknown>,
|
|
144
|
+
newTable: LuaMap<AnyNotNil, unknown>,
|
|
145
145
|
traversalDescription: string,
|
|
146
146
|
) {
|
|
147
147
|
iterateTableInOrder(
|
|
@@ -170,12 +170,12 @@ function mergeTable(
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
if (isTable(value)) {
|
|
173
|
-
let oldValue = oldTable.get(key) as
|
|
173
|
+
let oldValue = oldTable.get(key) as LuaMap<AnyNotNil, unknown>;
|
|
174
174
|
if (!isTable(oldValue)) {
|
|
175
175
|
// The child table does not exist on the old table. However, we still need to copy over
|
|
176
176
|
// the new table, because we need to handle data types like "Foo | null". Thus, set up a
|
|
177
177
|
// blank sub-table on the old table, and continue to recursively merge..
|
|
178
|
-
oldValue = new
|
|
178
|
+
oldValue = new LuaMap();
|
|
179
179
|
oldTable.set(key, oldValue);
|
|
180
180
|
}
|
|
181
181
|
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
|
|
12
12
|
export function saveToDisk(
|
|
13
13
|
mod: Mod,
|
|
14
|
-
saveDataMap:
|
|
15
|
-
saveDataConditionalFuncMap:
|
|
14
|
+
saveDataMap: LuaMap<string, SaveData>,
|
|
15
|
+
saveDataConditionalFuncMap: LuaMap<string, () => boolean>,
|
|
16
16
|
): void {
|
|
17
17
|
const allSaveData = getAllSaveDataToWriteToDisk(
|
|
18
18
|
saveDataMap,
|
|
@@ -26,10 +26,10 @@ export function saveToDisk(
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function getAllSaveDataToWriteToDisk(
|
|
29
|
-
saveDataMap:
|
|
30
|
-
saveDataConditionalFuncMap:
|
|
29
|
+
saveDataMap: LuaMap<string, SaveData>,
|
|
30
|
+
saveDataConditionalFuncMap: LuaMap<string, () => boolean>,
|
|
31
31
|
) {
|
|
32
|
-
const allSaveData = new
|
|
32
|
+
const allSaveData = new LuaMap<AnyNotNil, unknown>();
|
|
33
33
|
|
|
34
34
|
iterateTableInOrder(
|
|
35
35
|
saveDataMap,
|
|
@@ -60,7 +60,7 @@ function getAllSaveDataToWriteToDisk(
|
|
|
60
60
|
// that is unnecessary. Make a copy of the data and recursively convert all TypeScriptToLua
|
|
61
61
|
// Maps into Lua tables.
|
|
62
62
|
const saveDataCopy = deepCopy(
|
|
63
|
-
saveDataWithoutRoom as
|
|
63
|
+
saveDataWithoutRoom as LuaMap,
|
|
64
64
|
SerializationType.SERIALIZE,
|
|
65
65
|
subscriberName,
|
|
66
66
|
);
|
|
File without changes
|
package/src/functions/array.ts
CHANGED
|
@@ -443,9 +443,7 @@ export function isArray(object: unknown): object is unknown[] {
|
|
|
443
443
|
return false;
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
-
// Third, handle the case of an "empty" table.
|
|
447
|
-
// determine this, since that will not actually return the number of keys. (It will only work
|
|
448
|
-
// properly for tables that are being used as arrays, which is not necessarily the case here.)
|
|
446
|
+
// Third, handle the case of an "empty" table.
|
|
449
447
|
const tableLength = Object.keys(object).length;
|
|
450
448
|
if (tableLength === 0) {
|
|
451
449
|
return true;
|
|
@@ -453,7 +451,7 @@ export function isArray(object: unknown): object is unknown[] {
|
|
|
453
451
|
|
|
454
452
|
// Third, check for non-contiguous elements. (Lua tables start at an index of 1.)
|
|
455
453
|
for (let i = 1; i <= tableLength; i++) {
|
|
456
|
-
const element = object.get(i)
|
|
454
|
+
const element = object.get(i);
|
|
457
455
|
if (element === undefined) {
|
|
458
456
|
return false;
|
|
459
457
|
}
|
package/src/functions/color.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { isaacAPIClassEquals, isIsaacAPIClassOfType } from "./isaacAPIClass";
|
|
|
4
4
|
import { copyValuesToTable, getNumbersFromTable, tableHasKeys } from "./table";
|
|
5
5
|
import { isTable } from "./types";
|
|
6
6
|
|
|
7
|
-
type SerializedColor =
|
|
7
|
+
type SerializedColor = LuaMap<string, unknown> & {
|
|
8
8
|
readonly __serializedColorBrand: symbol;
|
|
9
9
|
};
|
|
10
10
|
|
|
@@ -65,7 +65,7 @@ export function copyColor(
|
|
|
65
65
|
);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const colorTable = new
|
|
68
|
+
const colorTable = new LuaMap<string, unknown>();
|
|
69
69
|
copyValuesToTable(color, KEYS, colorTable);
|
|
70
70
|
colorTable.set(SerializationBrand.COLOR, "");
|
|
71
71
|
return colorTable as SerializedColor;
|
|
@@ -79,7 +79,7 @@ export function copyColor(
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const [r, g, b, a, ro, go, bo] = getNumbersFromTable(
|
|
82
|
-
color as
|
|
82
|
+
color as LuaMap<string, unknown>,
|
|
83
83
|
OBJECT_NAME,
|
|
84
84
|
...KEYS,
|
|
85
85
|
);
|
|
@@ -3,12 +3,12 @@ import { CopyableIsaacAPIClassType } from "../enums/private/CopyableIsaacAPIClas
|
|
|
3
3
|
import { SerializationBrand } from "../enums/private/SerializationBrand";
|
|
4
4
|
import { SerializationType } from "../enums/SerializationType";
|
|
5
5
|
import { SAVE_DATA_MANAGER_DEBUG } from "../features/saveDataManager/saveDataManagerConstants";
|
|
6
|
-
import { isSerializationBrand } from "../features/saveDataManager/
|
|
6
|
+
import { isSerializationBrand } from "../features/saveDataManager/serializationBrands";
|
|
7
7
|
import { TSTLClass } from "../types/private/TSTLClass";
|
|
8
8
|
import { isArray } from "./array";
|
|
9
9
|
import { getEnumValues } from "./enums";
|
|
10
10
|
import { getIsaacAPIClassName } from "./isaacAPIClass";
|
|
11
|
-
import { log
|
|
11
|
+
import { log } from "./log";
|
|
12
12
|
import {
|
|
13
13
|
copyIsaacAPIClass,
|
|
14
14
|
deserializeIsaacAPIClass,
|
|
@@ -36,7 +36,7 @@ const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
|
|
|
36
36
|
* It supports the following object types:
|
|
37
37
|
*
|
|
38
38
|
* - Primitives (i.e. strings, numbers, and booleans)
|
|
39
|
-
* -
|
|
39
|
+
* - Basic TSTL objects / tables
|
|
40
40
|
* - TSTL `Map`
|
|
41
41
|
* - TSTL `Set`
|
|
42
42
|
* - TSTL classes
|
|
@@ -101,9 +101,9 @@ export function deepCopy(
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
case "table": {
|
|
104
|
-
const
|
|
104
|
+
const luaMap = value as LuaMap<AnyNotNil, unknown>;
|
|
105
105
|
return deepCopyTable(
|
|
106
|
-
|
|
106
|
+
luaMap,
|
|
107
107
|
serializationType,
|
|
108
108
|
traversalDescription,
|
|
109
109
|
insideMap,
|
|
@@ -117,40 +117,40 @@ export function deepCopy(
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function deepCopyTable(
|
|
120
|
-
|
|
120
|
+
luaMap: LuaMap<AnyNotNil, unknown>,
|
|
121
121
|
serializationType: SerializationType,
|
|
122
122
|
traversalDescription: string,
|
|
123
123
|
insideMap: boolean,
|
|
124
124
|
) {
|
|
125
125
|
// First, handle the cases of TSTL classes or serialized TSTL classes.
|
|
126
|
-
if (isDefaultMap(
|
|
126
|
+
if (isDefaultMap(luaMap) || luaMap.has(SerializationBrand.DEFAULT_MAP)) {
|
|
127
127
|
return deepCopyDefaultMap(
|
|
128
|
-
|
|
128
|
+
luaMap,
|
|
129
129
|
serializationType,
|
|
130
130
|
traversalDescription,
|
|
131
131
|
insideMap,
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
if (isTSTLMap(
|
|
135
|
+
if (isTSTLMap(luaMap) || luaMap.has(SerializationBrand.MAP)) {
|
|
136
136
|
return deepCopyMap(
|
|
137
|
-
|
|
137
|
+
luaMap,
|
|
138
138
|
serializationType,
|
|
139
139
|
traversalDescription,
|
|
140
140
|
insideMap,
|
|
141
141
|
);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
if (isTSTLSet(
|
|
144
|
+
if (isTSTLSet(luaMap) || luaMap.has(SerializationBrand.SET)) {
|
|
145
145
|
return deepCopySet(
|
|
146
|
-
|
|
146
|
+
luaMap,
|
|
147
147
|
serializationType,
|
|
148
148
|
traversalDescription,
|
|
149
149
|
insideMap,
|
|
150
150
|
);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
const className = getTSTLClassName(
|
|
153
|
+
const className = getTSTLClassName(luaMap);
|
|
154
154
|
|
|
155
155
|
if (className === "WeakMap") {
|
|
156
156
|
error(
|
|
@@ -164,9 +164,9 @@ function deepCopyTable(
|
|
|
164
164
|
);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
if (isUserDefinedTSTLClass(
|
|
167
|
+
if (isUserDefinedTSTLClass(luaMap)) {
|
|
168
168
|
return deepCopyTSTLClass(
|
|
169
|
-
|
|
169
|
+
luaMap,
|
|
170
170
|
serializationType,
|
|
171
171
|
traversalDescription,
|
|
172
172
|
insideMap,
|
|
@@ -174,20 +174,20 @@ function deepCopyTable(
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// This is not a TSTL Map/Set/class. If it has a metatable, abort.
|
|
177
|
-
checkMetatable(
|
|
177
|
+
checkMetatable(luaMap, traversalDescription);
|
|
178
178
|
|
|
179
179
|
// Handle the special case of serialized Isaac API classes.
|
|
180
180
|
if (
|
|
181
|
-
isSerializedIsaacAPIClass(
|
|
181
|
+
isSerializedIsaacAPIClass(luaMap) &&
|
|
182
182
|
serializationType === SerializationType.DESERIALIZE
|
|
183
183
|
) {
|
|
184
|
-
return deserializeIsaacAPIClass(
|
|
184
|
+
return deserializeIsaacAPIClass(luaMap);
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
// Handle the special case of an array.
|
|
188
|
-
if (isArray(
|
|
188
|
+
if (isArray(luaMap)) {
|
|
189
189
|
return deepCopyArray(
|
|
190
|
-
|
|
190
|
+
luaMap,
|
|
191
191
|
serializationType,
|
|
192
192
|
traversalDescription,
|
|
193
193
|
insideMap,
|
|
@@ -196,7 +196,7 @@ function deepCopyTable(
|
|
|
196
196
|
|
|
197
197
|
// Base case: copy a normal Lua table
|
|
198
198
|
return deepCopyNormalLuaTable(
|
|
199
|
-
|
|
199
|
+
luaMap,
|
|
200
200
|
serializationType,
|
|
201
201
|
traversalDescription,
|
|
202
202
|
insideMap,
|
|
@@ -204,11 +204,16 @@ function deepCopyTable(
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
function deepCopyDefaultMap(
|
|
207
|
-
defaultMap: DefaultMap<AnyNotNil, unknown> |
|
|
207
|
+
defaultMap: DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
|
|
208
208
|
serializationType: SerializationType,
|
|
209
209
|
traversalDescription: string,
|
|
210
210
|
insideMap: boolean,
|
|
211
211
|
) {
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
213
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
214
|
+
log("deepCopy is copying a DefaultMap.");
|
|
215
|
+
}
|
|
216
|
+
|
|
212
217
|
const constructorArg = isDefaultMap(defaultMap)
|
|
213
218
|
? defaultMap.getConstructorArg()
|
|
214
219
|
: undefined; // The undefined case is handled explicitly in the "getNewDefaultMap" function.
|
|
@@ -287,11 +292,11 @@ function deepCopyDefaultMap(
|
|
|
287
292
|
* whether we are serializing or not.
|
|
288
293
|
*/
|
|
289
294
|
function getNewDefaultMap(
|
|
290
|
-
defaultMap: DefaultMap<AnyNotNil, unknown> |
|
|
295
|
+
defaultMap: DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
|
|
291
296
|
serializationType: SerializationType,
|
|
292
297
|
traversalDescription: string,
|
|
293
298
|
constructorArg: unknown,
|
|
294
|
-
) {
|
|
299
|
+
): DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown> {
|
|
295
300
|
switch (serializationType) {
|
|
296
301
|
case SerializationType.NONE: {
|
|
297
302
|
// eslint-disable-next-line isaacscript/no-invalid-default-map
|
|
@@ -301,7 +306,7 @@ function getNewDefaultMap(
|
|
|
301
306
|
case SerializationType.SERIALIZE: {
|
|
302
307
|
// Since we are serializing, the new object will be a Lua table. (At this point, we already
|
|
303
308
|
// handled the special case of a DefaultMap instantiated with a factory function.)
|
|
304
|
-
const newDefaultMap = new
|
|
309
|
+
const newDefaultMap = new LuaMap<AnyNotNil, unknown>();
|
|
305
310
|
newDefaultMap.set(SerializationBrand.DEFAULT_MAP, "");
|
|
306
311
|
newDefaultMap.set(SerializationBrand.DEFAULT_MAP_VALUE, constructorArg);
|
|
307
312
|
|
|
@@ -331,15 +336,20 @@ function getNewDefaultMap(
|
|
|
331
336
|
}
|
|
332
337
|
|
|
333
338
|
function deepCopyMap(
|
|
334
|
-
map: Map<AnyNotNil, unknown> |
|
|
339
|
+
map: Map<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
|
|
335
340
|
serializationType: SerializationType,
|
|
336
341
|
traversalDescription: string,
|
|
337
342
|
insideMap: boolean,
|
|
338
343
|
) {
|
|
339
|
-
|
|
344
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
345
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
346
|
+
log("deepCopy is copying a Map.");
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
let newMap: Map<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>;
|
|
340
350
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
341
351
|
// Since we are serializing, the new object will be a Lua table.
|
|
342
|
-
newMap = new
|
|
352
|
+
newMap = new LuaMap<AnyNotNil, unknown>();
|
|
343
353
|
newMap.set(SerializationBrand.MAP, "");
|
|
344
354
|
} else {
|
|
345
355
|
newMap = new Map();
|
|
@@ -379,16 +389,21 @@ function deepCopyMap(
|
|
|
379
389
|
}
|
|
380
390
|
|
|
381
391
|
function deepCopySet(
|
|
382
|
-
set: Set<AnyNotNil> |
|
|
392
|
+
set: Set<AnyNotNil> | LuaMap<AnyNotNil, unknown>,
|
|
383
393
|
serializationType: SerializationType,
|
|
384
394
|
traversalDescription: string,
|
|
385
395
|
insideMap: boolean,
|
|
386
396
|
) {
|
|
387
|
-
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
398
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
399
|
+
log("deepCopy is copying a Set.");
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
let newSet: Set<AnyNotNil> | LuaMap<AnyNotNil, string>;
|
|
388
403
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
389
404
|
// For serialization purposes, we represent a `Set` as a table with keys that match the
|
|
390
405
|
// keys/values in the Set and values of an empty string.
|
|
391
|
-
newSet = new
|
|
406
|
+
newSet = new LuaMap<AnyNotNil, string>();
|
|
392
407
|
newSet.set(SerializationBrand.SET, "");
|
|
393
408
|
} else {
|
|
394
409
|
newSet = new Set();
|
|
@@ -405,7 +420,7 @@ function deepCopySet(
|
|
|
405
420
|
// Differentiating between the two types looks superfluous but is necessary for TSTL to produce
|
|
406
421
|
// the proper set method call.
|
|
407
422
|
if (isTSTLSet(newSet)) {
|
|
408
|
-
// We should never be serializing an object of type Set
|
|
423
|
+
// We should never be serializing an object of type `Set`.
|
|
409
424
|
error(
|
|
410
425
|
"The deep copy function cannot convert number keys to strings for a Set.",
|
|
411
426
|
);
|
|
@@ -433,10 +448,15 @@ function deepCopyTSTLClass(
|
|
|
433
448
|
traversalDescription: string,
|
|
434
449
|
insideMap: boolean,
|
|
435
450
|
) {
|
|
436
|
-
|
|
451
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
452
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
453
|
+
log("deepCopy is copying a TSTL class.");
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
let newClass: TSTLClass | LuaMap<AnyNotNil, unknown>;
|
|
437
457
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
438
458
|
// Since we are serializing, the new object will be a Lua table.
|
|
439
|
-
newClass = new
|
|
459
|
+
newClass = new LuaMap<AnyNotNil, unknown>();
|
|
440
460
|
// (We do not brand it with the class type because we will not have the associated class
|
|
441
461
|
// constructor during deserialization, so knowing what type of class it is is pointless.)
|
|
442
462
|
} else {
|
|
@@ -467,6 +487,11 @@ function deepCopyArray(
|
|
|
467
487
|
traversalDescription: string,
|
|
468
488
|
insideMap: boolean,
|
|
469
489
|
) {
|
|
490
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
491
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
492
|
+
log("deepCopy is copying an array.");
|
|
493
|
+
}
|
|
494
|
+
|
|
470
495
|
const newArray: unknown[] = [];
|
|
471
496
|
|
|
472
497
|
for (const value of array) {
|
|
@@ -483,14 +508,19 @@ function deepCopyArray(
|
|
|
483
508
|
}
|
|
484
509
|
|
|
485
510
|
function deepCopyNormalLuaTable(
|
|
486
|
-
|
|
511
|
+
luaMap: LuaMap<AnyNotNil, unknown>,
|
|
487
512
|
serializationType: SerializationType,
|
|
488
513
|
traversalDescription: string,
|
|
489
514
|
insideMap: boolean,
|
|
490
515
|
) {
|
|
491
|
-
|
|
516
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
517
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
518
|
+
log("deepCopy is copying a normal Lua table.");
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const newTable = new LuaMap<AnyNotNil, unknown>();
|
|
492
522
|
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(
|
|
493
|
-
|
|
523
|
+
luaMap,
|
|
494
524
|
serializationType,
|
|
495
525
|
traversalDescription,
|
|
496
526
|
insideMap,
|
|
@@ -535,10 +565,17 @@ function getCopiedEntries(
|
|
|
535
565
|
|
|
536
566
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
537
567
|
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
538
|
-
logTable(entries);
|
|
539
568
|
entries.sort(twoDimensionalSort);
|
|
540
569
|
}
|
|
541
570
|
|
|
571
|
+
// During serialization, we brand some Lua tables with a special identifier to signify that it has
|
|
572
|
+
// keys that should be deserialized to numbers.
|
|
573
|
+
const convertStringKeysToNumbers =
|
|
574
|
+
serializationType === SerializationType.DESERIALIZE &&
|
|
575
|
+
entries.some(
|
|
576
|
+
([key]) => key === (SerializationBrand.OBJECT_WITH_NUMBER_KEYS as string),
|
|
577
|
+
);
|
|
578
|
+
|
|
542
579
|
const hasNumberKeys = entries.some(([key]) => isNumber(key));
|
|
543
580
|
const convertNumberKeysToStrings =
|
|
544
581
|
serializationType === SerializationType.SERIALIZE && hasNumberKeys;
|
|
@@ -560,7 +597,16 @@ function getCopiedEntries(
|
|
|
560
597
|
insideMap,
|
|
561
598
|
);
|
|
562
599
|
|
|
563
|
-
|
|
600
|
+
let keyToUse = key;
|
|
601
|
+
if (convertStringKeysToNumbers) {
|
|
602
|
+
const numberKey = tonumber(key);
|
|
603
|
+
if (numberKey !== undefined) {
|
|
604
|
+
keyToUse = numberKey;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (convertNumberKeysToStrings) {
|
|
608
|
+
keyToUse = tostring(key);
|
|
609
|
+
}
|
|
564
610
|
copiedEntries.push([keyToUse, newValue]);
|
|
565
611
|
}
|
|
566
612
|
|
|
@@ -575,8 +621,11 @@ function getCopiedEntries(
|
|
|
575
621
|
* copy function will refuse to copy a table type that has a metatable, outside of specifically
|
|
576
622
|
* supported TSTL objects.
|
|
577
623
|
*/
|
|
578
|
-
function checkMetatable(
|
|
579
|
-
|
|
624
|
+
function checkMetatable(
|
|
625
|
+
luaMap: LuaMap<AnyNotNil, unknown>,
|
|
626
|
+
traversalDescription: string,
|
|
627
|
+
) {
|
|
628
|
+
const metatable = getmetatable(luaMap);
|
|
580
629
|
if (metatable === undefined) {
|
|
581
630
|
return;
|
|
582
631
|
}
|
|
@@ -597,6 +646,11 @@ function deepCopyUserdata(
|
|
|
597
646
|
serializationType: SerializationType,
|
|
598
647
|
traversalDescription: string,
|
|
599
648
|
) {
|
|
649
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
650
|
+
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
651
|
+
log("deepCopy is copying userdata.");
|
|
652
|
+
}
|
|
653
|
+
|
|
600
654
|
const classType = getIsaacAPIClassName(value);
|
|
601
655
|
if (classType === undefined) {
|
|
602
656
|
error(
|