isaacscript-common 15.3.0 → 15.3.1

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/index.d.ts CHANGED
@@ -10721,12 +10721,22 @@ declare class ModdedElementSets extends Feature {
10721
10721
  */
10722
10722
  export declare class ModFeature {
10723
10723
  private mod;
10724
+ private initialized;
10724
10725
  constructor(mod: ModUpgradedBase, init?: boolean);
10725
10726
  /**
10726
10727
  * Runs the `Mod.AddCallback` and `ModUpgraded.AddCallbackCustom` methods for all of the decorated
10727
10728
  * callbacks. Additionally, subscribes the `v` object to the save data manager, if present.
10729
+ *
10730
+ * @param init Optional. Whether to initialize or uninitialize. Default is true.
10728
10731
  */
10729
10732
  init(init?: boolean): void;
10733
+ /**
10734
+ * Runs the `Mod.RemoveCallback` and `ModUpgraded.RemoveCallbackCustom` methods for all of the
10735
+ * decorated callbacks. Additionally, unsubscribes the `v` object from the save data manager, if
10736
+ * present.
10737
+ *
10738
+ * This is just an alias for `ModFeature.init(false)`.
10739
+ */
10730
10740
  uninit(): void;
10731
10741
  }
10732
10742
 
@@ -1,6 +1,6 @@
1
1
  --[[
2
2
 
3
- isaacscript-common 15.3.0
3
+ isaacscript-common 15.3.1
4
4
 
5
5
  This is the "isaacscript-common" library, which was created with the IsaacScript tool.
6
6
 
@@ -48341,8 +48341,9 @@ return ____exports
48341
48341
  local ____lualib = require("lualib_bundle")
48342
48342
  local __TS__Class = ____lualib.__TS__Class
48343
48343
  local Map = ____lualib.Map
48344
+ local __TS__New = ____lualib.__TS__New
48344
48345
  local ____exports = {}
48345
- local initDecoratedCallbacks, initSaveDataManager, WRAPPED_CALLBACK_METHODS_KEY, WRAPPED_CUSTOM_CALLBACK_METHODS_KEY
48346
+ local initDecoratedCallbacks, addCallback, removeCallback, initSaveDataManager, WRAPPED_CALLBACK_METHODS_KEY, WRAPPED_CUSTOM_CALLBACK_METHODS_KEY
48346
48347
  local ____array = require("src.functions.array")
48347
48348
  local isArray = ____array.isArray
48348
48349
  local ____deepCopy = require("src.functions.deepCopy")
@@ -48351,6 +48352,8 @@ local ____tstlClass = require("src.functions.tstlClass")
48351
48352
  local getTSTLClassConstructor = ____tstlClass.getTSTLClassConstructor
48352
48353
  local getTSTLClassName = ____tstlClass.getTSTLClassName
48353
48354
  local ____types = require("src.functions.types")
48355
+ local isFunction = ____types.isFunction
48356
+ local isNumber = ____types.isNumber
48354
48357
  local isTable = ____types.isTable
48355
48358
  function initDecoratedCallbacks(self, modFeature, constructor, tstlClassName, vanilla, init)
48356
48359
  local modFeatureConstructor = constructor
@@ -48368,51 +48371,88 @@ function initDecoratedCallbacks(self, modFeature, constructor, tstlClassName, va
48368
48371
  end
48369
48372
  local parameters = deepCopy(nil, args)
48370
48373
  local modCallback = table.remove(parameters, 1)
48371
- if modCallback == nil then
48374
+ if not isNumber(nil, modCallback) then
48372
48375
  error("Failed to get the callback number from the parameters for class: " .. tstlClassName)
48373
48376
  end
48374
48377
  local callback = table.remove(parameters, 1)
48375
- if callback == nil then
48378
+ if not isFunction(nil, callback) then
48376
48379
  error("Failed to get the callback function from the parameters for class: " .. tstlClassName)
48377
48380
  end
48378
48381
  local mod = modFeature.mod
48379
48382
  if init then
48380
- local function wrappedCallback(____, ...)
48381
- callback(modFeature, ...)
48382
- end
48383
- if vanilla then
48384
- local modCallbackVanilla = modCallback
48385
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
48386
- wrappedMethodsMap:set(modCallbackVanilla, wrappedCallback)
48387
- else
48388
- local modCallbackCustom = modCallback
48389
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
48390
- wrappedMethodsMap:set(modCallbackCustom, wrappedCallback)
48391
- end
48392
- if vanilla then
48393
- mod:AddCallback(
48394
- modCallback,
48395
- wrappedCallback,
48396
- table.unpack(parameters)
48397
- )
48398
- else
48399
- mod:AddCallbackCustom(
48400
- modCallback,
48401
- wrappedCallback,
48402
- table.unpack(parameters)
48403
- )
48404
- end
48405
- elseif vanilla then
48406
- local modCallbackVanilla = modCallback
48407
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
48408
- local wrappedCallback = wrappedMethodsMap:get(modCallbackVanilla)
48409
- mod:RemoveCallback(modCallback, wrappedCallback)
48383
+ addCallback(
48384
+ nil,
48385
+ modFeature,
48386
+ modFeatureConstructor,
48387
+ mod,
48388
+ modCallback,
48389
+ callback,
48390
+ parameters,
48391
+ vanilla
48392
+ )
48410
48393
  else
48411
- local modCallbackCustom = modCallback
48412
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
48413
- local wrappedCallback = wrappedMethodsMap:get(modCallbackCustom)
48414
- mod:RemoveCallbackCustom(modCallback, wrappedCallback)
48394
+ removeCallback(
48395
+ nil,
48396
+ modFeatureConstructor,
48397
+ mod,
48398
+ modCallback,
48399
+ vanilla
48400
+ )
48401
+ end
48402
+ end
48403
+ end
48404
+ function addCallback(self, modFeature, modFeatureConstructor, mod, modCallback, callback, parameters, vanilla)
48405
+ local function wrappedCallback(____, ...)
48406
+ callback(nil, modFeature, ...)
48407
+ end
48408
+ if vanilla then
48409
+ local modCallbackVanilla = modCallback
48410
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
48411
+ if wrappedMethodsMap == nil then
48412
+ wrappedMethodsMap = __TS__New(Map)
48413
+ modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY] = wrappedMethodsMap
48415
48414
  end
48415
+ wrappedMethodsMap:set(modCallbackVanilla, wrappedCallback)
48416
+ else
48417
+ local modCallbackCustom = modCallback
48418
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
48419
+ if wrappedMethodsMap == nil then
48420
+ wrappedMethodsMap = __TS__New(Map)
48421
+ modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY] = wrappedMethodsMap
48422
+ end
48423
+ wrappedMethodsMap:set(modCallbackCustom, wrappedCallback)
48424
+ end
48425
+ if vanilla then
48426
+ mod:AddCallback(
48427
+ modCallback,
48428
+ wrappedCallback,
48429
+ table.unpack(parameters)
48430
+ )
48431
+ else
48432
+ mod:AddCallbackCustom(
48433
+ modCallback,
48434
+ wrappedCallback,
48435
+ table.unpack(parameters)
48436
+ )
48437
+ end
48438
+ end
48439
+ function removeCallback(self, modFeatureConstructor, mod, modCallback, vanilla)
48440
+ if vanilla then
48441
+ local modCallbackVanilla = modCallback
48442
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
48443
+ if wrappedMethodsMap == nil then
48444
+ return
48445
+ end
48446
+ local wrappedCallback = wrappedMethodsMap:get(modCallbackVanilla)
48447
+ mod:RemoveCallback(modCallback, wrappedCallback)
48448
+ else
48449
+ local modCallbackCustom = modCallback
48450
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
48451
+ if wrappedMethodsMap == nil then
48452
+ return
48453
+ end
48454
+ local wrappedCallback = wrappedMethodsMap:get(modCallbackCustom)
48455
+ mod:RemoveCallbackCustom(modCallback, wrappedCallback)
48416
48456
  end
48417
48457
  end
48418
48458
  function initSaveDataManager(self, modFeature, tstlClassName, init)
@@ -48450,6 +48490,7 @@ function ModFeature.prototype.____constructor(self, mod, init)
48450
48490
  if init == nil then
48451
48491
  init = true
48452
48492
  end
48493
+ self.initialized = false
48453
48494
  self.mod = mod
48454
48495
  if init then
48455
48496
  self:init()
@@ -48459,11 +48500,15 @@ function ModFeature.prototype.init(self, init)
48459
48500
  if init == nil then
48460
48501
  init = true
48461
48502
  end
48503
+ if self.initialized == init then
48504
+ return
48505
+ end
48506
+ self.initialized = init
48462
48507
  local constructor = getTSTLClassConstructor(nil, self)
48463
48508
  if constructor == nil then
48464
48509
  error("Failed to get the TSTL class constructor for a mod feature.")
48465
48510
  end
48466
- local tstlClassName = getTSTLClassName(nil, constructor)
48511
+ local tstlClassName = getTSTLClassName(nil, self)
48467
48512
  if tstlClassName == nil then
48468
48513
  error("Failed to get the TSTL class name for a mod feature.")
48469
48514
  end
@@ -33,12 +33,22 @@ export declare const ADD_CALLBACK_CUSTOM_ARGS_KEY = "__addCallbackCustomArgs";
33
33
  */
34
34
  export declare class ModFeature {
35
35
  private mod;
36
+ private initialized;
36
37
  constructor(mod: ModUpgradedBase, init?: boolean);
37
38
  /**
38
39
  * Runs the `Mod.AddCallback` and `ModUpgraded.AddCallbackCustom` methods for all of the decorated
39
40
  * callbacks. Additionally, subscribes the `v` object to the save data manager, if present.
41
+ *
42
+ * @param init Optional. Whether to initialize or uninitialize. Default is true.
40
43
  */
41
44
  init(init?: boolean): void;
45
+ /**
46
+ * Runs the `Mod.RemoveCallback` and `ModUpgraded.RemoveCallbackCustom` methods for all of the
47
+ * decorated callbacks. Additionally, unsubscribes the `v` object from the save data manager, if
48
+ * present.
49
+ *
50
+ * This is just an alias for `ModFeature.init(false)`.
51
+ */
42
52
  uninit(): void;
43
53
  }
44
54
  //# sourceMappingURL=ModFeature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModFeature.d.ts","sourceRoot":"","sources":["../../../src/classes/ModFeature.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAWtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAkB;gBAEjB,GAAG,EAAE,eAAe,EAAE,IAAI,UAAO;IAQ7C;;;OAGG;IACI,IAAI,CAAC,IAAI,UAAO,GAAG,IAAI;IAgBvB,MAAM,IAAI,IAAI;CAGtB"}
1
+ {"version":3,"file":"ModFeature.d.ts","sourceRoot":"","sources":["../../../src/classes/ModFeature.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAatE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,WAAW,CAAS;gBAEhB,GAAG,EAAE,eAAe,EAAE,IAAI,UAAO;IAQ7C;;;;;OAKG;IACI,IAAI,CAAC,IAAI,UAAO,GAAG,IAAI;IAqB9B;;;;;;OAMG;IACI,MAAM,IAAI,IAAI;CAGtB"}
@@ -1,8 +1,9 @@
1
1
  local ____lualib = require("lualib_bundle")
2
2
  local __TS__Class = ____lualib.__TS__Class
3
3
  local Map = ____lualib.Map
4
+ local __TS__New = ____lualib.__TS__New
4
5
  local ____exports = {}
5
- local initDecoratedCallbacks, initSaveDataManager, WRAPPED_CALLBACK_METHODS_KEY, WRAPPED_CUSTOM_CALLBACK_METHODS_KEY
6
+ local initDecoratedCallbacks, addCallback, removeCallback, initSaveDataManager, WRAPPED_CALLBACK_METHODS_KEY, WRAPPED_CUSTOM_CALLBACK_METHODS_KEY
6
7
  local ____array = require("src.functions.array")
7
8
  local isArray = ____array.isArray
8
9
  local ____deepCopy = require("src.functions.deepCopy")
@@ -11,6 +12,8 @@ local ____tstlClass = require("src.functions.tstlClass")
11
12
  local getTSTLClassConstructor = ____tstlClass.getTSTLClassConstructor
12
13
  local getTSTLClassName = ____tstlClass.getTSTLClassName
13
14
  local ____types = require("src.functions.types")
15
+ local isFunction = ____types.isFunction
16
+ local isNumber = ____types.isNumber
14
17
  local isTable = ____types.isTable
15
18
  function initDecoratedCallbacks(self, modFeature, constructor, tstlClassName, vanilla, init)
16
19
  local modFeatureConstructor = constructor
@@ -28,53 +31,90 @@ function initDecoratedCallbacks(self, modFeature, constructor, tstlClassName, va
28
31
  end
29
32
  local parameters = deepCopy(nil, args)
30
33
  local modCallback = table.remove(parameters, 1)
31
- if modCallback == nil then
34
+ if not isNumber(nil, modCallback) then
32
35
  error("Failed to get the callback number from the parameters for class: " .. tstlClassName)
33
36
  end
34
37
  local callback = table.remove(parameters, 1)
35
- if callback == nil then
38
+ if not isFunction(nil, callback) then
36
39
  error("Failed to get the callback function from the parameters for class: " .. tstlClassName)
37
40
  end
38
41
  local mod = modFeature.mod
39
42
  if init then
40
- local function wrappedCallback(____, ...)
41
- callback(modFeature, ...)
42
- end
43
- if vanilla then
44
- local modCallbackVanilla = modCallback
45
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
46
- wrappedMethodsMap:set(modCallbackVanilla, wrappedCallback)
47
- else
48
- local modCallbackCustom = modCallback
49
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
50
- wrappedMethodsMap:set(modCallbackCustom, wrappedCallback)
51
- end
52
- if vanilla then
53
- mod:AddCallback(
54
- modCallback,
55
- wrappedCallback,
56
- table.unpack(parameters)
57
- )
58
- else
59
- mod:AddCallbackCustom(
60
- modCallback,
61
- wrappedCallback,
62
- table.unpack(parameters)
63
- )
64
- end
65
- elseif vanilla then
66
- local modCallbackVanilla = modCallback
67
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
68
- local wrappedCallback = wrappedMethodsMap:get(modCallbackVanilla)
69
- mod:RemoveCallback(modCallback, wrappedCallback)
43
+ addCallback(
44
+ nil,
45
+ modFeature,
46
+ modFeatureConstructor,
47
+ mod,
48
+ modCallback,
49
+ callback,
50
+ parameters,
51
+ vanilla
52
+ )
70
53
  else
71
- local modCallbackCustom = modCallback
72
- local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
73
- local wrappedCallback = wrappedMethodsMap:get(modCallbackCustom)
74
- mod:RemoveCallbackCustom(modCallback, wrappedCallback)
54
+ removeCallback(
55
+ nil,
56
+ modFeatureConstructor,
57
+ mod,
58
+ modCallback,
59
+ vanilla
60
+ )
75
61
  end
76
62
  end
77
63
  end
64
+ function addCallback(self, modFeature, modFeatureConstructor, mod, modCallback, callback, parameters, vanilla)
65
+ local function wrappedCallback(____, ...)
66
+ callback(nil, modFeature, ...)
67
+ end
68
+ if vanilla then
69
+ local modCallbackVanilla = modCallback
70
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
71
+ if wrappedMethodsMap == nil then
72
+ wrappedMethodsMap = __TS__New(Map)
73
+ modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY] = wrappedMethodsMap
74
+ end
75
+ wrappedMethodsMap:set(modCallbackVanilla, wrappedCallback)
76
+ else
77
+ local modCallbackCustom = modCallback
78
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
79
+ if wrappedMethodsMap == nil then
80
+ wrappedMethodsMap = __TS__New(Map)
81
+ modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY] = wrappedMethodsMap
82
+ end
83
+ wrappedMethodsMap:set(modCallbackCustom, wrappedCallback)
84
+ end
85
+ if vanilla then
86
+ mod:AddCallback(
87
+ modCallback,
88
+ wrappedCallback,
89
+ table.unpack(parameters)
90
+ )
91
+ else
92
+ mod:AddCallbackCustom(
93
+ modCallback,
94
+ wrappedCallback,
95
+ table.unpack(parameters)
96
+ )
97
+ end
98
+ end
99
+ function removeCallback(self, modFeatureConstructor, mod, modCallback, vanilla)
100
+ if vanilla then
101
+ local modCallbackVanilla = modCallback
102
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY]
103
+ if wrappedMethodsMap == nil then
104
+ return
105
+ end
106
+ local wrappedCallback = wrappedMethodsMap:get(modCallbackVanilla)
107
+ mod:RemoveCallback(modCallback, wrappedCallback)
108
+ else
109
+ local modCallbackCustom = modCallback
110
+ local wrappedMethodsMap = modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]
111
+ if wrappedMethodsMap == nil then
112
+ return
113
+ end
114
+ local wrappedCallback = wrappedMethodsMap:get(modCallbackCustom)
115
+ mod:RemoveCallbackCustom(modCallback, wrappedCallback)
116
+ end
117
+ end
78
118
  function initSaveDataManager(self, modFeature, tstlClassName, init)
79
119
  local ____modFeature_0 = modFeature
80
120
  local v = ____modFeature_0.v
@@ -138,6 +178,7 @@ function ModFeature.prototype.____constructor(self, mod, init)
138
178
  if init == nil then
139
179
  init = true
140
180
  end
181
+ self.initialized = false
141
182
  self.mod = mod
142
183
  if init then
143
184
  self:init()
@@ -147,11 +188,15 @@ function ModFeature.prototype.init(self, init)
147
188
  if init == nil then
148
189
  init = true
149
190
  end
191
+ if self.initialized == init then
192
+ return
193
+ end
194
+ self.initialized = init
150
195
  local constructor = getTSTLClassConstructor(nil, self)
151
196
  if constructor == nil then
152
197
  error("Failed to get the TSTL class constructor for a mod feature.")
153
198
  end
154
- local tstlClassName = getTSTLClassName(nil, constructor)
199
+ local tstlClassName = getTSTLClassName(nil, self)
155
200
  if tstlClassName == nil then
156
201
  error("Failed to get the TSTL class name for a mod feature.")
157
202
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "15.3.0",
3
+ "version": "15.3.1",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -22,6 +22,6 @@
22
22
  "main": "dist/src/index",
23
23
  "types": "dist/src/index.d.ts",
24
24
  "dependencies": {
25
- "isaac-typescript-definitions": "^9.0.3"
25
+ "isaac-typescript-definitions": "^9.0.4"
26
26
  }
27
27
  }
@@ -6,7 +6,7 @@ import {
6
6
  getTSTLClassConstructor,
7
7
  getTSTLClassName,
8
8
  } from "../functions/tstlClass";
9
- import { isTable } from "../functions/types";
9
+ import { isFunction, isNumber, isTable } from "../functions/types";
10
10
  import { TSTLClassMetatable } from "../interfaces/TSTLClassMetatable";
11
11
  import { AnyFunction } from "../types/AnyFunction";
12
12
  import { ModUpgradedBase } from "./ModUpgradedBase";
@@ -19,8 +19,10 @@ const WRAPPED_CUSTOM_CALLBACK_METHODS_KEY = "__wrappedCustomCallbacksMethods";
19
19
  type ModFeatureConstructor = TSTLClassMetatable["constructor"] & {
20
20
  [ADD_CALLBACK_ARGS_KEY]: unknown | undefined;
21
21
  [ADD_CALLBACK_CUSTOM_ARGS_KEY]: unknown | undefined;
22
- [WRAPPED_CALLBACK_METHODS_KEY]: Map<ModCallback, AnyFunction>;
23
- [WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]: Map<ModCallbackCustom, AnyFunction>;
22
+ [WRAPPED_CALLBACK_METHODS_KEY]: Map<ModCallback, AnyFunction> | undefined;
23
+ [WRAPPED_CUSTOM_CALLBACK_METHODS_KEY]:
24
+ | Map<ModCallbackCustom, AnyFunction>
25
+ | undefined;
24
26
  };
25
27
 
26
28
  /**
@@ -56,6 +58,7 @@ type ModFeatureConstructor = TSTLClassMetatable["constructor"] & {
56
58
 
57
59
  export class ModFeature {
58
60
  private mod: ModUpgradedBase;
61
+ private initialized = false;
59
62
 
60
63
  constructor(mod: ModUpgradedBase, init = true) {
61
64
  this.mod = mod;
@@ -68,14 +71,21 @@ export class ModFeature {
68
71
  /**
69
72
  * Runs the `Mod.AddCallback` and `ModUpgraded.AddCallbackCustom` methods for all of the decorated
70
73
  * callbacks. Additionally, subscribes the `v` object to the save data manager, if present.
74
+ *
75
+ * @param init Optional. Whether to initialize or uninitialize. Default is true.
71
76
  */
72
77
  public init(init = true): void {
78
+ if (this.initialized === init) {
79
+ return;
80
+ }
81
+ this.initialized = init;
82
+
73
83
  const constructor = getTSTLClassConstructor(this);
74
84
  if (constructor === undefined) {
75
85
  error("Failed to get the TSTL class constructor for a mod feature.");
76
86
  }
77
87
 
78
- const tstlClassName = getTSTLClassName(constructor);
88
+ const tstlClassName = getTSTLClassName(this);
79
89
  if (tstlClassName === undefined) {
80
90
  error("Failed to get the TSTL class name for a mod feature.");
81
91
  }
@@ -85,6 +95,13 @@ export class ModFeature {
85
95
  initSaveDataManager(this, tstlClassName, init);
86
96
  }
87
97
 
98
+ /**
99
+ * Runs the `Mod.RemoveCallback` and `ModUpgraded.RemoveCallbackCustom` methods for all of the
100
+ * decorated callbacks. Additionally, unsubscribes the `v` object from the save data manager, if
101
+ * present.
102
+ *
103
+ * This is just an alias for `ModFeature.init(false)`.
104
+ */
88
105
  public uninit(): void {
89
106
  this.init(false);
90
107
  }
@@ -122,16 +139,14 @@ function initDecoratedCallbacks(
122
139
  const parameters = deepCopy(args);
123
140
 
124
141
  const modCallback = parameters.shift();
125
- if (modCallback === undefined) {
142
+ if (!isNumber(modCallback)) {
126
143
  error(
127
144
  `Failed to get the callback number from the parameters for class: ${tstlClassName}`,
128
145
  );
129
146
  }
130
147
 
131
- const callback = parameters.shift() as
132
- | ((this: void, ...callbackArgs: unknown[]) => void)
133
- | undefined;
134
- if (callback === undefined) {
148
+ const callback = parameters.shift();
149
+ if (!isFunction(callback)) {
135
150
  error(
136
151
  `Failed to get the callback function from the parameters for class: ${tstlClassName}`,
137
152
  );
@@ -141,51 +156,99 @@ function initDecoratedCallbacks(
141
156
  const mod = modFeature["mod"];
142
157
 
143
158
  if (init) {
144
- // We need to wrap the callback in a new function so that we can explicitly pass the class as
145
- // the first argument. (Otherwise, the method will not be able to properly access `this`.
146
- const wrappedCallback = (...callbackArgs: unknown[]) => {
147
- callback(modFeature, ...callbackArgs);
148
- };
149
-
150
- // We need to save the wrapped function for later (so we can unregister them).
151
- if (vanilla) {
152
- const modCallbackVanilla = modCallback as ModCallback;
153
- const wrappedMethodsMap =
154
- modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY];
155
- wrappedMethodsMap.set(modCallbackVanilla, wrappedCallback);
156
- } else {
157
- const modCallbackCustom = modCallback as ModCallbackCustom;
158
- const wrappedMethodsMap =
159
- modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY];
160
- wrappedMethodsMap.set(modCallbackCustom, wrappedCallback);
161
- }
162
-
163
- if (vanilla) {
164
- (mod.AddCallback as AnyFunction)(
165
- modCallback,
166
- wrappedCallback,
167
- ...parameters,
168
- );
169
- } else {
170
- (mod.AddCallbackCustom as AnyFunction)(
171
- modCallback,
172
- wrappedCallback,
173
- ...parameters,
174
- );
175
- }
176
- } else if (vanilla) {
177
- const modCallbackVanilla = modCallback as ModCallback;
178
- const wrappedMethodsMap =
179
- modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY];
180
- const wrappedCallback = wrappedMethodsMap.get(modCallbackVanilla);
181
- (mod.RemoveCallback as AnyFunction)(modCallback, wrappedCallback);
159
+ addCallback(
160
+ modFeature,
161
+ modFeatureConstructor,
162
+ mod,
163
+ modCallback,
164
+ callback,
165
+ parameters,
166
+ vanilla,
167
+ );
182
168
  } else {
183
- const modCallbackCustom = modCallback as ModCallbackCustom;
184
- const wrappedMethodsMap =
185
- modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY];
186
- const wrappedCallback = wrappedMethodsMap.get(modCallbackCustom);
187
- (mod.RemoveCallbackCustom as AnyFunction)(modCallback, wrappedCallback);
169
+ removeCallback(modFeatureConstructor, mod, modCallback, vanilla);
170
+ }
171
+ }
172
+ }
173
+
174
+ function addCallback(
175
+ modFeature: ModFeature,
176
+ modFeatureConstructor: ModFeatureConstructor,
177
+ mod: ModUpgradedBase,
178
+ modCallback: unknown,
179
+ // eslint-disable-next-line @typescript-eslint/ban-types
180
+ callback: Function,
181
+ parameters: unknown[],
182
+ vanilla: boolean,
183
+ ) {
184
+ // We need to wrap the callback in a new function so that we can explicitly pass the class as the
185
+ // first argument. (Otherwise, the method will not be able to properly access `this`.
186
+ const wrappedCallback = (...callbackArgs: unknown[]) => {
187
+ callback(modFeature, ...callbackArgs);
188
+ };
189
+
190
+ // We need to save the wrapped function for later (so we can unregister them).
191
+ if (vanilla) {
192
+ const modCallbackVanilla = modCallback as ModCallback;
193
+ let wrappedMethodsMap = modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY];
194
+ if (wrappedMethodsMap === undefined) {
195
+ wrappedMethodsMap = new Map();
196
+ modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY] = wrappedMethodsMap;
197
+ }
198
+ wrappedMethodsMap.set(modCallbackVanilla, wrappedCallback);
199
+ } else {
200
+ const modCallbackCustom = modCallback as ModCallbackCustom;
201
+ let wrappedMethodsMap =
202
+ modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY];
203
+ if (wrappedMethodsMap === undefined) {
204
+ wrappedMethodsMap = new Map();
205
+ modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY] =
206
+ wrappedMethodsMap;
188
207
  }
208
+ wrappedMethodsMap.set(modCallbackCustom, wrappedCallback);
209
+ }
210
+
211
+ if (vanilla) {
212
+ (mod.AddCallback as AnyFunction)(
213
+ modCallback,
214
+ wrappedCallback,
215
+ ...parameters,
216
+ );
217
+ } else {
218
+ (mod.AddCallbackCustom as AnyFunction)(
219
+ modCallback,
220
+ wrappedCallback,
221
+ ...parameters,
222
+ );
223
+ }
224
+ }
225
+
226
+ function removeCallback(
227
+ modFeatureConstructor: ModFeatureConstructor,
228
+ mod: ModUpgradedBase,
229
+ modCallback: unknown,
230
+ vanilla: boolean,
231
+ ) {
232
+ if (vanilla) {
233
+ const modCallbackVanilla = modCallback as ModCallback;
234
+ const wrappedMethodsMap =
235
+ modFeatureConstructor[WRAPPED_CALLBACK_METHODS_KEY];
236
+ if (wrappedMethodsMap === undefined) {
237
+ return;
238
+ }
239
+
240
+ const wrappedCallback = wrappedMethodsMap.get(modCallbackVanilla);
241
+ (mod.RemoveCallback as AnyFunction)(modCallback, wrappedCallback);
242
+ } else {
243
+ const modCallbackCustom = modCallback as ModCallbackCustom;
244
+ const wrappedMethodsMap =
245
+ modFeatureConstructor[WRAPPED_CUSTOM_CALLBACK_METHODS_KEY];
246
+ if (wrappedMethodsMap === undefined) {
247
+ return;
248
+ }
249
+
250
+ const wrappedCallback = wrappedMethodsMap.get(modCallbackCustom);
251
+ (mod.RemoveCallbackCustom as AnyFunction)(modCallback, wrappedCallback);
189
252
  }
190
253
  }
191
254