isaacscript-common 6.6.2 → 6.6.5
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/callbacks/postCustomDoorEnter.d.ts +1 -1
- package/dist/callbacks/postCustomDoorEnter.lua +1 -1
- package/dist/enums/private/SerializationBrand.d.ts +0 -4
- package/dist/enums/private/SerializationBrand.d.ts.map +1 -1
- package/dist/features/customStage/shadows.d.ts.map +1 -1
- package/dist/features/customStage/shadows.lua +0 -2
- package/dist/features/saveDataManager/merge.lua +4 -3
- package/dist/functions/array.d.ts.map +1 -1
- package/dist/functions/array.lua +1 -1
- package/dist/functions/deepCopy.d.ts +8 -5
- package/dist/functions/deepCopy.d.ts.map +1 -1
- package/dist/functions/deepCopy.lua +142 -38
- package/dist/functions/deepCopyTests.d.ts +6 -1
- package/dist/functions/deepCopyTests.d.ts.map +1 -1
- package/dist/functions/deepCopyTests.lua +19 -16
- package/dist/functions/log.d.ts +1 -1
- package/dist/functions/log.d.ts.map +1 -1
- package/dist/functions/log.lua +8 -4
- package/dist/functions/mergeTests.d.ts +7 -1
- package/dist/functions/mergeTests.d.ts.map +1 -1
- package/dist/functions/mergeTests.lua +86 -7
- package/dist/functions/playerIndex.d.ts +4 -0
- package/dist/functions/playerIndex.d.ts.map +1 -1
- package/dist/functions/playerIndex.lua +4 -0
- package/dist/functions/table.d.ts +1 -1
- package/dist/functions/table.lua +1 -1
- package/package.json +2 -2
- package/src/callbacks/postCursedTeleport.ts +1 -1
- package/src/callbacks/postCustomDoorEnter.ts +1 -1
- package/src/callbacks/postPlayerCollectible.ts +1 -1
- package/src/callbacks/postSacrifice.ts +1 -1
- package/src/enums/private/SerializationBrand.ts +0 -4
- package/src/features/customStage/shadows.ts +0 -6
- package/src/features/extraConsoleCommands/listCommands.ts +3 -3
- package/src/features/persistentEntities.ts +1 -1
- package/src/features/saveDataManager/merge.ts +3 -3
- package/src/functions/array.ts +5 -2
- package/src/functions/bitwise.ts +2 -2
- package/src/functions/deepCopy.ts +98 -19
- package/src/functions/deepCopyTests.ts +75 -19
- package/src/functions/log.ts +16 -7
- package/src/functions/mergeTests.ts +152 -4
- package/src/functions/playerIndex.ts +4 -0
- package/src/functions/table.ts +1 -1
- package/src/functions/trinketGive.ts +3 -3
- package/src/functions/tstlClass.ts +1 -1
- package/src/functions/ui.ts +3 -3
|
@@ -51,15 +51,19 @@ const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
|
|
|
51
51
|
* - other Isaac API objects such as `EntityPtr` (that have a type of "userdata")
|
|
52
52
|
*
|
|
53
53
|
* @param value The primitive or object to copy.
|
|
54
|
-
* @param serializationType Has 3 possible values. Can
|
|
55
|
-
* to Lua tables, or can deserialize Lua tables to
|
|
56
|
-
* `SerializationType.NONE`.
|
|
57
|
-
* @param traversalDescription Used to track the current key that we are operating on.
|
|
54
|
+
* @param serializationType Optional. Has 3 possible values. Can copy objects as-is, or can
|
|
55
|
+
* serialize objects to Lua tables, or can deserialize Lua tables to
|
|
56
|
+
* objects. Default is `SerializationType.NONE`.
|
|
57
|
+
* @param traversalDescription Optional. Used to track the current key that we are operating on.
|
|
58
|
+
* Default is an empty string.
|
|
59
|
+
* @param insideMap Optional. Tracks whether or not the deep copy function is in the process of
|
|
60
|
+
* recursively copying a TSTL Map. Default is false.
|
|
58
61
|
*/
|
|
59
62
|
export function deepCopy(
|
|
60
63
|
value: unknown,
|
|
61
64
|
serializationType = SerializationType.NONE,
|
|
62
65
|
traversalDescription = "",
|
|
66
|
+
insideMap = false,
|
|
63
67
|
): unknown {
|
|
64
68
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
65
69
|
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
@@ -98,7 +102,12 @@ export function deepCopy(
|
|
|
98
102
|
|
|
99
103
|
case "table": {
|
|
100
104
|
const luaTable = value as LuaTable<AnyNotNil, unknown>;
|
|
101
|
-
return deepCopyTable(
|
|
105
|
+
return deepCopyTable(
|
|
106
|
+
luaTable,
|
|
107
|
+
serializationType,
|
|
108
|
+
traversalDescription,
|
|
109
|
+
insideMap,
|
|
110
|
+
);
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
case "userdata": {
|
|
@@ -111,6 +120,7 @@ function deepCopyTable(
|
|
|
111
120
|
luaTable: LuaTable<AnyNotNil, unknown>,
|
|
112
121
|
serializationType: SerializationType,
|
|
113
122
|
traversalDescription: string,
|
|
123
|
+
insideMap: boolean,
|
|
114
124
|
) {
|
|
115
125
|
// First, handle the cases of TSTL classes or serialized TSTL classes.
|
|
116
126
|
if (isDefaultMap(luaTable) || luaTable.has(SerializationBrand.DEFAULT_MAP)) {
|
|
@@ -118,15 +128,26 @@ function deepCopyTable(
|
|
|
118
128
|
luaTable,
|
|
119
129
|
serializationType,
|
|
120
130
|
traversalDescription,
|
|
131
|
+
insideMap,
|
|
121
132
|
);
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
if (isTSTLMap(luaTable) || luaTable.has(SerializationBrand.MAP)) {
|
|
125
|
-
return deepCopyMap(
|
|
136
|
+
return deepCopyMap(
|
|
137
|
+
luaTable,
|
|
138
|
+
serializationType,
|
|
139
|
+
traversalDescription,
|
|
140
|
+
insideMap,
|
|
141
|
+
);
|
|
126
142
|
}
|
|
127
143
|
|
|
128
144
|
if (isTSTLSet(luaTable) || luaTable.has(SerializationBrand.SET)) {
|
|
129
|
-
return deepCopySet(
|
|
145
|
+
return deepCopySet(
|
|
146
|
+
luaTable,
|
|
147
|
+
serializationType,
|
|
148
|
+
traversalDescription,
|
|
149
|
+
insideMap,
|
|
150
|
+
);
|
|
130
151
|
}
|
|
131
152
|
|
|
132
153
|
const className = getTSTLClassName(luaTable);
|
|
@@ -144,7 +165,12 @@ function deepCopyTable(
|
|
|
144
165
|
}
|
|
145
166
|
|
|
146
167
|
if (isUserDefinedTSTLClass(luaTable)) {
|
|
147
|
-
return deepCopyTSTLClass(
|
|
168
|
+
return deepCopyTSTLClass(
|
|
169
|
+
luaTable,
|
|
170
|
+
serializationType,
|
|
171
|
+
traversalDescription,
|
|
172
|
+
insideMap,
|
|
173
|
+
);
|
|
148
174
|
}
|
|
149
175
|
|
|
150
176
|
// This is not a TSTL Map/Set/class. If it has a metatable, abort.
|
|
@@ -160,7 +186,12 @@ function deepCopyTable(
|
|
|
160
186
|
|
|
161
187
|
// Handle the special case of an array.
|
|
162
188
|
if (isArray(luaTable)) {
|
|
163
|
-
return deepCopyArray(
|
|
189
|
+
return deepCopyArray(
|
|
190
|
+
luaTable,
|
|
191
|
+
serializationType,
|
|
192
|
+
traversalDescription,
|
|
193
|
+
insideMap,
|
|
194
|
+
);
|
|
164
195
|
}
|
|
165
196
|
|
|
166
197
|
// Base case: copy a normal Lua table
|
|
@@ -168,6 +199,7 @@ function deepCopyTable(
|
|
|
168
199
|
luaTable,
|
|
169
200
|
serializationType,
|
|
170
201
|
traversalDescription,
|
|
202
|
+
insideMap,
|
|
171
203
|
);
|
|
172
204
|
}
|
|
173
205
|
|
|
@@ -175,19 +207,39 @@ function deepCopyDefaultMap(
|
|
|
175
207
|
defaultMap: DefaultMap<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
|
|
176
208
|
serializationType: SerializationType,
|
|
177
209
|
traversalDescription: string,
|
|
210
|
+
insideMap: boolean,
|
|
178
211
|
) {
|
|
179
|
-
// First, handle the special case of serializing a DefaultMap instantiated with a factory
|
|
180
|
-
// function. If this is the case, then we cannot serialize it, so we serialize it as a normal
|
|
181
|
-
// `Map` instead. We do not throw a runtime error because the merge function does not need to
|
|
182
|
-
// instantiate the DefaultMap class in most circumstances.
|
|
183
212
|
const constructorArg = isDefaultMap(defaultMap)
|
|
184
213
|
? defaultMap.getConstructorArg()
|
|
185
|
-
: undefined;
|
|
214
|
+
: undefined; // The undefined case is handled explicitly in the "getNewDefaultMap" function.
|
|
215
|
+
|
|
216
|
+
// First, handle the special case of serializing a DefaultMap instantiated with a factory
|
|
217
|
+
// function. If this is the case, then we cannot serialize it (because there is no way to
|
|
218
|
+
// serialize a function).
|
|
186
219
|
if (
|
|
187
220
|
serializationType === SerializationType.SERIALIZE &&
|
|
188
221
|
!isPrimitive(constructorArg)
|
|
189
222
|
) {
|
|
190
|
-
|
|
223
|
+
if (insideMap) {
|
|
224
|
+
// The case of a DefaultMap within another map is complicated. Unlike a DefaultMap attached to
|
|
225
|
+
// a "normal" object, the `merge` function will have no reference to the factory function that
|
|
226
|
+
// was used to instantiate it. Thus, there is no way to copy this object. In this case, we
|
|
227
|
+
// throw a run-time error to immediately alert the end-user that their data structure is
|
|
228
|
+
// invalid.
|
|
229
|
+
error(
|
|
230
|
+
'Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of another map. You cannot use a nested DefaultMap in this way because factory functions are not serializable. (In other words, there is no way to copy the function that you are using for the DefaultMap into the "save#.dat" file.) Instead, refactor your data structure so that the DefaultMap is not nested.',
|
|
231
|
+
);
|
|
232
|
+
} else {
|
|
233
|
+
// In most cases, the DefaultMap will be attached to a normal table element. In this case, if
|
|
234
|
+
// we serialize it as a normal `Map`, then everything will work out fine, because the `merge`
|
|
235
|
+
// function only needs to copy the values (and not instantiate the object itself).
|
|
236
|
+
return deepCopyMap(
|
|
237
|
+
defaultMap,
|
|
238
|
+
serializationType,
|
|
239
|
+
traversalDescription,
|
|
240
|
+
insideMap,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
191
243
|
}
|
|
192
244
|
|
|
193
245
|
const newDefaultMap = getNewDefaultMap(
|
|
@@ -196,11 +248,13 @@ function deepCopyDefaultMap(
|
|
|
196
248
|
traversalDescription,
|
|
197
249
|
constructorArg,
|
|
198
250
|
);
|
|
251
|
+
insideMap = true;
|
|
199
252
|
|
|
200
253
|
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(
|
|
201
254
|
defaultMap,
|
|
202
255
|
serializationType,
|
|
203
256
|
traversalDescription,
|
|
257
|
+
insideMap,
|
|
204
258
|
);
|
|
205
259
|
|
|
206
260
|
if (convertedNumberKeysToStrings) {
|
|
@@ -223,12 +277,14 @@ function deepCopyDefaultMap(
|
|
|
223
277
|
}
|
|
224
278
|
}
|
|
225
279
|
|
|
280
|
+
insideMap = false;
|
|
281
|
+
|
|
226
282
|
return newDefaultMap;
|
|
227
283
|
}
|
|
228
284
|
|
|
229
285
|
/**
|
|
230
|
-
* The new default map with either be a TSTL `DefaultMap` class or a Lua table, depending on
|
|
231
|
-
* we are serializing or not.
|
|
286
|
+
* The new copied default map with either be a TSTL `DefaultMap` class or a Lua table, depending on
|
|
287
|
+
* whether we are serializing or not.
|
|
232
288
|
*/
|
|
233
289
|
function getNewDefaultMap(
|
|
234
290
|
defaultMap: DefaultMap<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
|
|
@@ -278,6 +334,7 @@ function deepCopyMap(
|
|
|
278
334
|
map: Map<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
|
|
279
335
|
serializationType: SerializationType,
|
|
280
336
|
traversalDescription: string,
|
|
337
|
+
insideMap: boolean,
|
|
281
338
|
) {
|
|
282
339
|
let newMap: Map<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>;
|
|
283
340
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
@@ -287,11 +344,13 @@ function deepCopyMap(
|
|
|
287
344
|
} else {
|
|
288
345
|
newMap = new Map();
|
|
289
346
|
}
|
|
347
|
+
insideMap = true;
|
|
290
348
|
|
|
291
349
|
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(
|
|
292
350
|
map,
|
|
293
351
|
serializationType,
|
|
294
352
|
traversalDescription,
|
|
353
|
+
insideMap,
|
|
295
354
|
);
|
|
296
355
|
|
|
297
356
|
if (convertedNumberKeysToStrings) {
|
|
@@ -314,6 +373,8 @@ function deepCopyMap(
|
|
|
314
373
|
}
|
|
315
374
|
}
|
|
316
375
|
|
|
376
|
+
insideMap = false;
|
|
377
|
+
|
|
317
378
|
return newMap;
|
|
318
379
|
}
|
|
319
380
|
|
|
@@ -321,6 +382,7 @@ function deepCopySet(
|
|
|
321
382
|
set: Set<AnyNotNil> | LuaTable<AnyNotNil, unknown>,
|
|
322
383
|
serializationType: SerializationType,
|
|
323
384
|
traversalDescription: string,
|
|
385
|
+
insideMap: boolean,
|
|
324
386
|
) {
|
|
325
387
|
let newSet: Set<AnyNotNil> | LuaTable<AnyNotNil, string>;
|
|
326
388
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
@@ -336,6 +398,7 @@ function deepCopySet(
|
|
|
336
398
|
set,
|
|
337
399
|
serializationType,
|
|
338
400
|
traversalDescription,
|
|
401
|
+
insideMap,
|
|
339
402
|
);
|
|
340
403
|
|
|
341
404
|
if (convertedNumberKeysToStrings) {
|
|
@@ -368,6 +431,7 @@ function deepCopyTSTLClass(
|
|
|
368
431
|
tstlClass: TSTLClass,
|
|
369
432
|
serializationType: SerializationType,
|
|
370
433
|
traversalDescription: string,
|
|
434
|
+
insideMap: boolean,
|
|
371
435
|
) {
|
|
372
436
|
let newClass: TSTLClass | LuaTable<AnyNotNil, unknown>;
|
|
373
437
|
if (serializationType === SerializationType.SERIALIZE) {
|
|
@@ -383,6 +447,7 @@ function deepCopyTSTLClass(
|
|
|
383
447
|
tstlClass,
|
|
384
448
|
serializationType,
|
|
385
449
|
traversalDescription,
|
|
450
|
+
insideMap,
|
|
386
451
|
);
|
|
387
452
|
|
|
388
453
|
if (convertedNumberKeysToStrings) {
|
|
@@ -400,11 +465,17 @@ function deepCopyArray(
|
|
|
400
465
|
array: unknown[],
|
|
401
466
|
serializationType: SerializationType,
|
|
402
467
|
traversalDescription: string,
|
|
468
|
+
insideMap: boolean,
|
|
403
469
|
) {
|
|
404
470
|
const newArray: unknown[] = [];
|
|
405
471
|
|
|
406
472
|
for (const value of array) {
|
|
407
|
-
const newValue = deepCopy(
|
|
473
|
+
const newValue = deepCopy(
|
|
474
|
+
value,
|
|
475
|
+
serializationType,
|
|
476
|
+
traversalDescription,
|
|
477
|
+
insideMap,
|
|
478
|
+
);
|
|
408
479
|
newArray.push(newValue);
|
|
409
480
|
}
|
|
410
481
|
|
|
@@ -415,12 +486,14 @@ function deepCopyNormalLuaTable(
|
|
|
415
486
|
luaTable: LuaTable<AnyNotNil, unknown>,
|
|
416
487
|
serializationType: SerializationType,
|
|
417
488
|
traversalDescription: string,
|
|
489
|
+
insideMap: boolean,
|
|
418
490
|
) {
|
|
419
491
|
const newTable = new LuaTable<AnyNotNil, unknown>();
|
|
420
492
|
const { entries, convertedNumberKeysToStrings } = getCopiedEntries(
|
|
421
493
|
luaTable,
|
|
422
494
|
serializationType,
|
|
423
495
|
traversalDescription,
|
|
496
|
+
insideMap,
|
|
424
497
|
);
|
|
425
498
|
|
|
426
499
|
if (convertedNumberKeysToStrings) {
|
|
@@ -442,6 +515,7 @@ function getCopiedEntries(
|
|
|
442
515
|
object: unknown,
|
|
443
516
|
serializationType: SerializationType,
|
|
444
517
|
traversalDescription: string,
|
|
518
|
+
insideMap: boolean,
|
|
445
519
|
): {
|
|
446
520
|
entries: Array<[key: AnyNotNil, value: unknown]>;
|
|
447
521
|
convertedNumberKeysToStrings: boolean;
|
|
@@ -479,7 +553,12 @@ function getCopiedEntries(
|
|
|
479
553
|
}
|
|
480
554
|
|
|
481
555
|
traversalDescription = getTraversalDescription(key, traversalDescription);
|
|
482
|
-
const newValue = deepCopy(
|
|
556
|
+
const newValue = deepCopy(
|
|
557
|
+
value,
|
|
558
|
+
serializationType,
|
|
559
|
+
traversalDescription,
|
|
560
|
+
insideMap,
|
|
561
|
+
);
|
|
483
562
|
|
|
484
563
|
const keyToUse = convertNumberKeysToStrings ? tostring(key) : key;
|
|
485
564
|
copiedEntries.push([keyToUse, newValue]);
|
|
@@ -7,7 +7,12 @@ import { log } from "./log";
|
|
|
7
7
|
import { isDefaultMap, isTSTLMap, isTSTLSet } from "./tstlClass";
|
|
8
8
|
import { isNumber, isString, isTable } from "./types";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Run the suite of tests that prove that the "deepCopy" helper function works properly.
|
|
12
|
+
*
|
|
13
|
+
* This function is only useful if you are troubleshooting the "deepCopy" function.
|
|
14
|
+
*/
|
|
15
|
+
export function runDeepCopyTests(): void {
|
|
11
16
|
copiedObjectIsTable();
|
|
12
17
|
copiedObjectHasKeyAndValueString();
|
|
13
18
|
copiedTableHasKeyAndValueNumber();
|
|
@@ -34,7 +39,11 @@ function copiedObjectIsTable() {
|
|
|
34
39
|
const oldObject = {
|
|
35
40
|
abc: "def",
|
|
36
41
|
};
|
|
37
|
-
const newObject = deepCopy(
|
|
42
|
+
const newObject = deepCopy(
|
|
43
|
+
oldObject as unknown as LuaTable,
|
|
44
|
+
SerializationType.NONE,
|
|
45
|
+
"copiedObjectIsTable",
|
|
46
|
+
);
|
|
38
47
|
if (!isTable(newObject)) {
|
|
39
48
|
error(`The copied object had a type of: ${typeof newObject}`);
|
|
40
49
|
}
|
|
@@ -46,7 +55,11 @@ function copiedObjectHasKeyAndValueString() {
|
|
|
46
55
|
const oldObject = {
|
|
47
56
|
abc: valueToLookFor,
|
|
48
57
|
};
|
|
49
|
-
const newTable = deepCopy(
|
|
58
|
+
const newTable = deepCopy(
|
|
59
|
+
oldObject as unknown as LuaTable,
|
|
60
|
+
SerializationType.NONE,
|
|
61
|
+
"copiedObjectHasKeyAndValueString",
|
|
62
|
+
);
|
|
50
63
|
const newObject = newTable as typeof oldObject;
|
|
51
64
|
|
|
52
65
|
const value = newObject[keyToLookFor];
|
|
@@ -69,7 +82,11 @@ function copiedTableHasKeyAndValueNumber() {
|
|
|
69
82
|
const oldTable = new LuaTable<AnyNotNil, unknown>();
|
|
70
83
|
oldTable.set(keyToLookFor, valueToLookFor);
|
|
71
84
|
|
|
72
|
-
const newObject = deepCopy(
|
|
85
|
+
const newObject = deepCopy(
|
|
86
|
+
oldTable,
|
|
87
|
+
SerializationType.NONE,
|
|
88
|
+
"copiedTableHasKeyAndValueNumber",
|
|
89
|
+
);
|
|
73
90
|
const newTable = newObject as LuaTable<AnyNotNil, unknown>;
|
|
74
91
|
|
|
75
92
|
const value = newTable.get(keyToLookFor) as number | undefined;
|
|
@@ -91,7 +108,11 @@ function copiedTableDoesNotCoerceTypes() {
|
|
|
91
108
|
const oldTable = new LuaTable<AnyNotNil, unknown>();
|
|
92
109
|
oldTable.set(keyToLookFor, valueToLookFor);
|
|
93
110
|
|
|
94
|
-
const newObject = deepCopy(
|
|
111
|
+
const newObject = deepCopy(
|
|
112
|
+
oldTable,
|
|
113
|
+
SerializationType.NONE,
|
|
114
|
+
"copiedTableDoesNotCoerceTypes",
|
|
115
|
+
);
|
|
95
116
|
const newTable = newObject as LuaTable<AnyNotNil, unknown>;
|
|
96
117
|
|
|
97
118
|
const keyString = tostring(keyToLookFor);
|
|
@@ -110,6 +131,7 @@ function copiedTableDoesNotCoerceTypes() {
|
|
|
110
131
|
}
|
|
111
132
|
}
|
|
112
133
|
|
|
134
|
+
/** In this context, a reference is a pointer. */
|
|
113
135
|
function copiedObjectHasNoReferencesForPrimitivesForward() {
|
|
114
136
|
const originalStringValue = "abcdef";
|
|
115
137
|
const originalNumberValue = 123;
|
|
@@ -117,7 +139,11 @@ function copiedObjectHasNoReferencesForPrimitivesForward() {
|
|
|
117
139
|
abc: originalStringValue,
|
|
118
140
|
def: originalNumberValue,
|
|
119
141
|
};
|
|
120
|
-
const newTable = deepCopy(
|
|
142
|
+
const newTable = deepCopy(
|
|
143
|
+
oldObject as unknown as LuaTable,
|
|
144
|
+
SerializationType.NONE,
|
|
145
|
+
"copiedObjectHasNoReferencesForPrimitivesForward",
|
|
146
|
+
);
|
|
121
147
|
const newObject = newTable as typeof oldObject;
|
|
122
148
|
|
|
123
149
|
oldObject.abc = "newValue";
|
|
@@ -138,7 +164,11 @@ function copiedObjectHasNoReferencesForPrimitivesBackward() {
|
|
|
138
164
|
abc: originalStringValue,
|
|
139
165
|
def: originalNumberValue,
|
|
140
166
|
};
|
|
141
|
-
const newTable = deepCopy(
|
|
167
|
+
const newTable = deepCopy(
|
|
168
|
+
oldObject as unknown as LuaTable,
|
|
169
|
+
SerializationType.NONE,
|
|
170
|
+
"copiedObjectHasNoReferencesForPrimitivesBackward",
|
|
171
|
+
);
|
|
142
172
|
const newObject = newTable as typeof oldObject;
|
|
143
173
|
|
|
144
174
|
newObject.abc = "newValue";
|
|
@@ -152,11 +182,16 @@ function copiedObjectHasNoReferencesForPrimitivesBackward() {
|
|
|
152
182
|
}
|
|
153
183
|
}
|
|
154
184
|
|
|
185
|
+
/** In this context, a reference is a pointer. */
|
|
155
186
|
function copiedObjectHasNoReferencesForArray() {
|
|
156
187
|
const oldObject = {
|
|
157
188
|
abc: [1, 2, 3],
|
|
158
189
|
};
|
|
159
|
-
const newTable = deepCopy(
|
|
190
|
+
const newTable = deepCopy(
|
|
191
|
+
oldObject as unknown as LuaTable,
|
|
192
|
+
SerializationType.NONE,
|
|
193
|
+
"copiedObjectHasNoReferencesForArray",
|
|
194
|
+
);
|
|
160
195
|
const newObject = newTable as typeof oldObject;
|
|
161
196
|
|
|
162
197
|
if (oldObject.abc === newObject.abc) {
|
|
@@ -167,21 +202,21 @@ function copiedObjectHasNoReferencesForArray() {
|
|
|
167
202
|
error("The copied object does not have an equal array.");
|
|
168
203
|
}
|
|
169
204
|
|
|
170
|
-
oldObject.abc[0]
|
|
205
|
+
oldObject.abc[0]++;
|
|
171
206
|
if (arrayEquals(oldObject.abc, newObject.abc)) {
|
|
172
207
|
error(
|
|
173
208
|
"The copied object has an equal array after a modification to the old array.",
|
|
174
209
|
);
|
|
175
210
|
}
|
|
176
|
-
oldObject.abc[0]
|
|
211
|
+
oldObject.abc[0]--;
|
|
177
212
|
|
|
178
|
-
newObject.abc[0]
|
|
213
|
+
newObject.abc[0]++;
|
|
179
214
|
if (arrayEquals(oldObject.abc, newObject.abc)) {
|
|
180
215
|
error(
|
|
181
216
|
"The copied object has an equal array after a modification to the new array.",
|
|
182
217
|
);
|
|
183
218
|
}
|
|
184
|
-
newObject.abc[0]
|
|
219
|
+
newObject.abc[0]--;
|
|
185
220
|
}
|
|
186
221
|
|
|
187
222
|
function copiedObjectHasChildObject() {
|
|
@@ -193,7 +228,11 @@ function copiedObjectHasChildObject() {
|
|
|
193
228
|
def: valueToLookFor,
|
|
194
229
|
},
|
|
195
230
|
};
|
|
196
|
-
const newTable = deepCopy(
|
|
231
|
+
const newTable = deepCopy(
|
|
232
|
+
oldObject as unknown as LuaTable,
|
|
233
|
+
SerializationType.NONE,
|
|
234
|
+
"copiedObjectHasChildObject",
|
|
235
|
+
);
|
|
197
236
|
const newObject = newTable as typeof oldObject;
|
|
198
237
|
|
|
199
238
|
const childObject = newObject[childObjectIndex];
|
|
@@ -226,7 +265,7 @@ function copiedMapIsMap() {
|
|
|
226
265
|
const oldMap = new Map<string, string>();
|
|
227
266
|
oldMap.set(keyToLookFor, valueToLookFor);
|
|
228
267
|
|
|
229
|
-
const newObject = deepCopy(oldMap);
|
|
268
|
+
const newObject = deepCopy(oldMap, SerializationType.NONE, "copiedMapIsMap");
|
|
230
269
|
const newMap = newObject as Map<string, string>;
|
|
231
270
|
|
|
232
271
|
if (!isTable(newMap)) {
|
|
@@ -243,7 +282,11 @@ function copiedMapHasValue() {
|
|
|
243
282
|
const oldMap = new Map<string, string>();
|
|
244
283
|
oldMap.set(keyToLookFor, valueToLookFor);
|
|
245
284
|
|
|
246
|
-
const newTable = deepCopy(
|
|
285
|
+
const newTable = deepCopy(
|
|
286
|
+
oldMap,
|
|
287
|
+
SerializationType.NONE,
|
|
288
|
+
"copiedMapHasValue",
|
|
289
|
+
);
|
|
247
290
|
const newMap = newTable as typeof oldMap;
|
|
248
291
|
|
|
249
292
|
const value = newMap.get(keyToLookFor);
|
|
@@ -260,7 +303,7 @@ function copiedSetIsSet() {
|
|
|
260
303
|
const oldSet = new Set<string>();
|
|
261
304
|
oldSet.add(valueToLookFor);
|
|
262
305
|
|
|
263
|
-
const newTable = deepCopy(oldSet);
|
|
306
|
+
const newTable = deepCopy(oldSet, SerializationType.NONE, "copiedSetIsSet");
|
|
264
307
|
const newSet = newTable as Set<string>;
|
|
265
308
|
|
|
266
309
|
if (!isTable(newSet)) {
|
|
@@ -276,7 +319,11 @@ function copiedSetHasValue() {
|
|
|
276
319
|
const oldSet = new Set<string>();
|
|
277
320
|
oldSet.add(valueToLookFor);
|
|
278
321
|
|
|
279
|
-
const newTable = deepCopy(
|
|
322
|
+
const newTable = deepCopy(
|
|
323
|
+
oldSet,
|
|
324
|
+
SerializationType.NONE,
|
|
325
|
+
"copiedSetHasValue",
|
|
326
|
+
);
|
|
280
327
|
const newSet = newTable as Set<string>;
|
|
281
328
|
|
|
282
329
|
const hasValue = newSet.has(valueToLookFor);
|
|
@@ -295,7 +342,11 @@ function copiedMapHasChildMap() {
|
|
|
295
342
|
const oldMap = new Map<string, Map<number, number>>();
|
|
296
343
|
oldMap.set(keyToLookFor, oldChildMap);
|
|
297
344
|
|
|
298
|
-
const newTable = deepCopy(
|
|
345
|
+
const newTable = deepCopy(
|
|
346
|
+
oldMap,
|
|
347
|
+
SerializationType.NONE,
|
|
348
|
+
"copiedMapHasChildMap",
|
|
349
|
+
);
|
|
299
350
|
const newMap = newTable as typeof oldMap;
|
|
300
351
|
|
|
301
352
|
const newChildMap = newMap.get(keyToLookFor);
|
|
@@ -332,7 +383,11 @@ function copiedDefaultMapHasChildDefaultMap() {
|
|
|
332
383
|
oldChildMap.getAndSetDefault(childMapKey1);
|
|
333
384
|
oldChildMap.set(childMapKey2, childMapCustomValue);
|
|
334
385
|
|
|
335
|
-
const newTable = deepCopy(
|
|
386
|
+
const newTable = deepCopy(
|
|
387
|
+
oldParentMap,
|
|
388
|
+
SerializationType.NONE,
|
|
389
|
+
"copiedDefaultMapHasChildDefaultMap",
|
|
390
|
+
);
|
|
336
391
|
const newParentMap = newTable as typeof oldParentMap;
|
|
337
392
|
|
|
338
393
|
const newChildMap = newParentMap.get(parentMapKey);
|
|
@@ -376,6 +431,7 @@ function copiedDefaultMapHasBrand() {
|
|
|
376
431
|
const newTable = deepCopy(
|
|
377
432
|
oldDefaultMap,
|
|
378
433
|
SerializationType.SERIALIZE,
|
|
434
|
+
"copiedDefaultMapHasBrand",
|
|
379
435
|
) as LuaTable<AnyNotNil, unknown>;
|
|
380
436
|
|
|
381
437
|
if (!newTable.has(SerializationBrand.DEFAULT_MAP)) {
|
package/src/functions/log.ts
CHANGED
|
@@ -228,7 +228,7 @@ export function logEntities(
|
|
|
228
228
|
msg += ` - CanShutDoors: ${npc.CanShutDoors}\n`;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
numMatchedEntities
|
|
231
|
+
numMatchedEntities++;
|
|
232
232
|
});
|
|
233
233
|
|
|
234
234
|
if (numMatchedEntities === 0) {
|
|
@@ -404,7 +404,7 @@ export function logGridEntities(
|
|
|
404
404
|
msg += ` - TargetRoomType: ${door.TargetRoomType}\n`;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
numMatchedEntities
|
|
407
|
+
numMatchedEntities++;
|
|
408
408
|
});
|
|
409
409
|
|
|
410
410
|
if (numMatchedEntities === 0) {
|
|
@@ -572,7 +572,7 @@ export function logSounds(this: void): void {
|
|
|
572
572
|
* recursively call itself if it counters a table within a table.
|
|
573
573
|
*
|
|
574
574
|
* This function will only work on tables that have string keys (because it logs the keys in order,
|
|
575
|
-
* instead of randomly). It will throw a
|
|
575
|
+
* instead of randomly). It will throw a run-time error if it encounters a non-string key.
|
|
576
576
|
*/
|
|
577
577
|
export function logTable(
|
|
578
578
|
this: void,
|
|
@@ -587,9 +587,14 @@ export function logTable(
|
|
|
587
587
|
const indentation = " ".repeat(numSpaces);
|
|
588
588
|
|
|
589
589
|
if (!isTable(luaTable)) {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
)
|
|
590
|
+
// Put it in an IIFE so that the it will show as "func" instead of "logTable" and align with the
|
|
591
|
+
// other text.
|
|
592
|
+
(() => {
|
|
593
|
+
log(
|
|
594
|
+
`${indentation}n/a (encountered a variable of type "${typeof luaTable}" instead of a table)`,
|
|
595
|
+
);
|
|
596
|
+
})();
|
|
597
|
+
|
|
593
598
|
return;
|
|
594
599
|
}
|
|
595
600
|
|
|
@@ -608,7 +613,11 @@ export function logTable(
|
|
|
608
613
|
}
|
|
609
614
|
});
|
|
610
615
|
|
|
611
|
-
|
|
616
|
+
// Put it in an IIFE so that the it will show as "func" instead of "logTable" and align with the
|
|
617
|
+
// other text.
|
|
618
|
+
(() => {
|
|
619
|
+
log(`${indentation}The size of the table was: ${luaTable.length()}`);
|
|
620
|
+
})();
|
|
612
621
|
}
|
|
613
622
|
|
|
614
623
|
/**
|