@eva/plugin-state-machine 2.1.0-beta.5 → 2.1.0-beta.6

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.
@@ -169,6 +169,38 @@ exports.StateMachine = StateMachine_1 = class StateMachine extends eva_js.Compon
169
169
  };
170
170
  pluginSignalBus.getSignalBus().emit(FSM_RESET_SIGNAL, resetPayload);
171
171
  }
172
+ /**
173
+ * 重发当前状态的 onEnter 信号(不 exit、不改 current、不重新订阅 transitions)。
174
+ *
175
+ * 用于 scene 切换 / restartScene 之后:globalEntities 上的 StateMachine 实例不销毁、
176
+ * 不发生状态转换,所以不会重发 onEnter;但本 scene 重建出的新 controller(如依赖
177
+ * `meta:fsm:enter:PLAYING` 激活的 cannon)需要这个信号才能 active。restartScene
178
+ * 完成后由 GlobalEntitiesManager 对 global StateMachine 调 reenterCurrent(),让新
179
+ * controller 收到 enter 信号(ADR-0017 选项 D)。
180
+ *
181
+ * 与 reset() 区别:reset 回 initial 并清订阅;reenterCurrent 保持当前状态,只补发
182
+ * onEnter(+ signalChange),订阅不动。
183
+ * 与 goto(current, {force}) 区别:force 会先 emit onExit 再重新订阅;reenterCurrent
184
+ * 不 exit、不重订阅(订阅还活着),更轻,适合 scene 切换后补发。
185
+ *
186
+ * 当前没进入任何状态(init 前)时是 no-op。
187
+ */
188
+ reenterCurrent(payload) {
189
+ if (!this.current)
190
+ return;
191
+ const cfg = this.states[this.current];
192
+ if (!cfg)
193
+ return;
194
+ const from = this.current;
195
+ const to = this.current;
196
+ const bus = pluginSignalBus.getSignalBus();
197
+ if (cfg.onEnter) {
198
+ bus.emit(cfg.onEnter, Object.assign({ from, to, reason: 'reenter' }, (payload || {})));
199
+ }
200
+ if (this.signalChange) {
201
+ bus.emit(this.signalChange, { from, to, reason: 'reenter' });
202
+ }
203
+ }
172
204
  get state() {
173
205
  return this.current;
174
206
  }
@@ -251,14 +283,17 @@ class StateMachineSystem extends eva_js.System {
251
283
  super(...arguments);
252
284
  this.name = 'StateMachine';
253
285
  this.emitSceneSwitch = true;
286
+ this.autoResetOnSceneSwitch = false;
254
287
  this.sceneChangedHandler = null;
255
288
  }
256
289
  init(params) {
257
290
  if ((params === null || params === void 0 ? void 0 : params.emitSceneSwitch) === false)
258
291
  this.emitSceneSwitch = false;
292
+ if ((params === null || params === void 0 ? void 0 : params.autoResetOnSceneSwitch) === true)
293
+ this.autoResetOnSceneSwitch = true;
259
294
  }
260
295
  awake() {
261
- if (!this.emitSceneSwitch)
296
+ if (!this.emitSceneSwitch && !this.autoResetOnSceneSwitch)
262
297
  return;
263
298
  if (!this.game)
264
299
  return;
@@ -268,11 +303,51 @@ class StateMachineSystem extends eva_js.System {
268
303
  const scene = raw && typeof raw === 'object' && 'scene' in raw
269
304
  ? raw.scene
270
305
  : undefined;
271
- const payload = { scene, raw };
272
- pluginSignalBus.getSignalBus().emit(FSM_SCENE_SWITCH_SIGNAL, payload);
306
+ if (this.emitSceneSwitch) {
307
+ const payload = { scene, raw };
308
+ pluginSignalBus.getSignalBus().emit(FSM_SCENE_SWITCH_SIGNAL, payload);
309
+ }
310
+ if (this.autoResetOnSceneSwitch) {
311
+ this.resetAllStateMachines();
312
+ }
273
313
  };
274
314
  this.game.on('sceneChanged', this.sceneChangedHandler);
275
315
  }
316
+ /**
317
+ * 遍历 game.gameObjects 找所有 StateMachine Component 调 reset()。
318
+ * 仅在 `autoResetOnSceneSwitch === true` 时被 awake 钩子调用。
319
+ *
320
+ * 注意:walk 失败时 swallow error 不抛(scene 切换 latency 路径不应被
321
+ * 单个 FSM 异常阻断,fsm.reset 内部已有 fail-safe console.warn)。
322
+ */
323
+ resetAllStateMachines() {
324
+ var _a, _b, _c, _d, _e;
325
+ if (!this.game)
326
+ return;
327
+ const gameObjects = (_a = this.game.gameObjects) !== null && _a !== void 0 ? _a : [];
328
+ for (const go of gameObjects) {
329
+ if (!go || typeof go !== 'object')
330
+ continue;
331
+ const comps = (_b = go.components) !== null && _b !== void 0 ? _b : [];
332
+ for (const comp of comps) {
333
+ if (!comp)
334
+ continue;
335
+ // duck-typing:同时识别 constructor.componentName 与 instance.name
336
+ const componentName = (_e = (_d = (_c = comp === null || comp === void 0 ? void 0 : comp.constructor) === null || _c === void 0 ? void 0 : _c.componentName) !== null && _d !== void 0 ? _d : comp === null || comp === void 0 ? void 0 : comp.name) !== null && _e !== void 0 ? _e : '';
337
+ if (componentName !== 'StateMachine')
338
+ continue;
339
+ if (typeof comp.reset !== 'function')
340
+ continue;
341
+ try {
342
+ comp.reset();
343
+ }
344
+ catch (err) {
345
+ // eslint-disable-next-line no-console
346
+ console.warn('[plugin-state-machine] auto-reset failed:', err);
347
+ }
348
+ }
349
+ }
350
+ }
276
351
  onDestroy() {
277
352
  if (this.sceneChangedHandler && this.game) {
278
353
  this.game.off('sceneChanged', this.sceneChangedHandler);
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t,e=require("@eva/eva.js"),s=require("@eva/plugin-signal-bus");"function"==typeof SuppressedError&&SuppressedError;const n="fsm:reset";exports.StateMachine=t=class extends e.Component{constructor(){super(...arguments),this.states={},this.current="",this.elapsedInState=0,this.subs=[],this.ctx={},this.initialState=""}init(t){var e,s;t&&(this.states=null!==(e=t.states)&&void 0!==e?e:{},this.signalChange=t.signalChange,this.ctx=null!==(s=t.context)&&void 0!==s?s:{},t.initial&&this.states[t.initial]&&(this.initialState=t.initial,this.enter(t.initial,"__init__")))}goto(t,e="manual"){var n;const{reason:i,force:a}=this.normalizeGotoOpts(e);if(!this.states[t])return void console.warn(`[plugin-state-machine] no such state: ${t}`);if(this.current===t&&!a)return;const r=this.current;r&&(null===(n=this.states[r])||void 0===n?void 0:n.onExit)&&s.getSignalBus().emit(this.states[r].onExit,{from:r,to:t,reason:i}),this.cleanupSubs(),this.enter(t,i)}normalizeGotoOpts(t){var e;return"string"==typeof t?{reason:t,force:!1}:{reason:null!==(e=t.reason)&&void 0!==e?e:"manual",force:!0===t.force}}reset(e){var i,a;const r=this.initialState;if(!r)return void console.warn("[plugin-state-machine] reset() called but no valid initial state");const o=this.current;o&&(null===(i=this.states[o])||void 0===i?void 0:i.onExit)&&s.getSignalBus().emit(this.states[o].onExit,{from:o,to:r,reason:"reset"}),this.cleanupSubs(),this.current="",this.enter(r,"reset");const c={entityId:null===(a=this.gameObject)||void 0===a?void 0:a.name,fsmName:t.componentName,fromState:o,payload:e};s.getSignalBus().emit(n,c)}get state(){return this.current}enter(t,e){var n;const i=this.current;this.current=t,this.elapsedInState=0;const a=this.states[t];if(!a)return;a.onEnter&&s.getSignalBus().emit(a.onEnter,{from:i,to:t,reason:e}),this.signalChange&&s.getSignalBus().emit(this.signalChange,{from:i,to:t,reason:e});const r=s.getSignalBus();for(const e of null!==(n=a.transitions)&&void 0!==n?n:[]){if(!e.on)continue;const s=e.to,n=e.guard,i=r.on(e.on,()=>{this.current===t&&(n&&!this.evalGuard(n)||this.goto(s,e.on))});this.subs.push(i)}}cleanupSubs(){for(const t of this.subs)t.dispose();this.subs=[]}evalGuard(t){try{const e=new Function("ctx",`return (${t});`);return Boolean(e(this.ctx))}catch(e){return console.warn(`[plugin-state-machine] bad guard "${t}":`,e),!1}}update(t){this.elapsedInState+=t.deltaTime;const e=this.states[this.current];if(null==e?void 0:e.transitions)for(const t of e.transitions)if(null!=t.after&&!(this.elapsedInState<t.after)&&(!t.guard||this.evalGuard(t.guard)))return void this.goto(t.to,`after:${t.after}`)}onDestroy(){this.cleanupSubs()}},exports.StateMachine.componentName="StateMachine",exports.StateMachine=t=function(t,e,s,n){var i,a=arguments.length,r=a<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,s):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,s,n);else for(var o=t.length-1;o>=0;o--)(i=t[o])&&(r=(a<3?i(r):a>3?i(e,s,r):i(e,s))||r);return a>3&&r&&Object.defineProperty(e,s,r),r}([e.decorators.componentObserver({})],exports.StateMachine);const i="fsm:scene-switch";class a extends e.System{constructor(){super(...arguments),this.name="StateMachine",this.emitSceneSwitch=!0,this.sceneChangedHandler=null}init(t){!1===(null==t?void 0:t.emitSceneSwitch)&&(this.emitSceneSwitch=!1)}awake(){this.emitSceneSwitch&&this.game&&(this.sceneChangedHandler=t=>{const e={scene:t&&"object"==typeof t&&"scene"in t?t.scene:void 0,raw:t};s.getSignalBus().emit(i,e)},this.game.on("sceneChanged",this.sceneChangedHandler))}onDestroy(){this.sceneChangedHandler&&this.game&&this.game.off("sceneChanged",this.sceneChangedHandler),this.sceneChangedHandler=null}}a.systemName="StateMachine",exports.FSM_RESET_SIGNAL=n,exports.FSM_SCENE_SWITCH_SIGNAL=i,exports.StateMachineSystem=a;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t,e=require("@eva/eva.js"),n=require("@eva/plugin-signal-bus");"function"==typeof SuppressedError&&SuppressedError;const s="fsm:reset";exports.StateMachine=t=class extends e.Component{constructor(){super(...arguments),this.states={},this.current="",this.elapsedInState=0,this.subs=[],this.ctx={},this.initialState=""}init(t){var e,n;t&&(this.states=null!==(e=t.states)&&void 0!==e?e:{},this.signalChange=t.signalChange,this.ctx=null!==(n=t.context)&&void 0!==n?n:{},t.initial&&this.states[t.initial]&&(this.initialState=t.initial,this.enter(t.initial,"__init__")))}goto(t,e="manual"){var s;const{reason:i,force:o}=this.normalizeGotoOpts(e);if(!this.states[t])return void console.warn(`[plugin-state-machine] no such state: ${t}`);if(this.current===t&&!o)return;const a=this.current;a&&(null===(s=this.states[a])||void 0===s?void 0:s.onExit)&&n.getSignalBus().emit(this.states[a].onExit,{from:a,to:t,reason:i}),this.cleanupSubs(),this.enter(t,i)}normalizeGotoOpts(t){var e;return"string"==typeof t?{reason:t,force:!1}:{reason:null!==(e=t.reason)&&void 0!==e?e:"manual",force:!0===t.force}}reset(e){var i,o;const a=this.initialState;if(!a)return void console.warn("[plugin-state-machine] reset() called but no valid initial state");const r=this.current;r&&(null===(i=this.states[r])||void 0===i?void 0:i.onExit)&&n.getSignalBus().emit(this.states[r].onExit,{from:r,to:a,reason:"reset"}),this.cleanupSubs(),this.current="",this.enter(a,"reset");const c={entityId:null===(o=this.gameObject)||void 0===o?void 0:o.name,fsmName:t.componentName,fromState:r,payload:e};n.getSignalBus().emit(s,c)}reenterCurrent(t){if(!this.current)return;const e=this.states[this.current];if(!e)return;const s=this.current,i=this.current,o=n.getSignalBus();e.onEnter&&o.emit(e.onEnter,Object.assign({from:s,to:i,reason:"reenter"},t||{})),this.signalChange&&o.emit(this.signalChange,{from:s,to:i,reason:"reenter"})}get state(){return this.current}enter(t,e){var s;const i=this.current;this.current=t,this.elapsedInState=0;const o=this.states[t];if(!o)return;o.onEnter&&n.getSignalBus().emit(o.onEnter,{from:i,to:t,reason:e}),this.signalChange&&n.getSignalBus().emit(this.signalChange,{from:i,to:t,reason:e});const a=n.getSignalBus();for(const e of null!==(s=o.transitions)&&void 0!==s?s:[]){if(!e.on)continue;const n=e.to,s=e.guard,i=a.on(e.on,()=>{this.current===t&&(s&&!this.evalGuard(s)||this.goto(n,e.on))});this.subs.push(i)}}cleanupSubs(){for(const t of this.subs)t.dispose();this.subs=[]}evalGuard(t){try{const e=new Function("ctx",`return (${t});`);return Boolean(e(this.ctx))}catch(e){return console.warn(`[plugin-state-machine] bad guard "${t}":`,e),!1}}update(t){this.elapsedInState+=t.deltaTime;const e=this.states[this.current];if(null==e?void 0:e.transitions)for(const t of e.transitions)if(null!=t.after&&!(this.elapsedInState<t.after)&&(!t.guard||this.evalGuard(t.guard)))return void this.goto(t.to,`after:${t.after}`)}onDestroy(){this.cleanupSubs()}},exports.StateMachine.componentName="StateMachine",exports.StateMachine=t=function(t,e,n,s){var i,o=arguments.length,a=o<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,n,s);else for(var r=t.length-1;r>=0;r--)(i=t[r])&&(a=(o<3?i(a):o>3?i(e,n,a):i(e,n))||a);return o>3&&a&&Object.defineProperty(e,n,a),a}([e.decorators.componentObserver({})],exports.StateMachine);const i="fsm:scene-switch";class o extends e.System{constructor(){super(...arguments),this.name="StateMachine",this.emitSceneSwitch=!0,this.autoResetOnSceneSwitch=!1,this.sceneChangedHandler=null}init(t){!1===(null==t?void 0:t.emitSceneSwitch)&&(this.emitSceneSwitch=!1),!0===(null==t?void 0:t.autoResetOnSceneSwitch)&&(this.autoResetOnSceneSwitch=!0)}awake(){(this.emitSceneSwitch||this.autoResetOnSceneSwitch)&&this.game&&(this.sceneChangedHandler=t=>{const e=t&&"object"==typeof t&&"scene"in t?t.scene:void 0;if(this.emitSceneSwitch){const s={scene:e,raw:t};n.getSignalBus().emit(i,s)}this.autoResetOnSceneSwitch&&this.resetAllStateMachines()},this.game.on("sceneChanged",this.sceneChangedHandler))}resetAllStateMachines(){var t,e,n,s,i;if(!this.game)return;const o=null!==(t=this.game.gameObjects)&&void 0!==t?t:[];for(const t of o){if(!t||"object"!=typeof t)continue;const o=null!==(e=t.components)&&void 0!==e?e:[];for(const t of o){if(!t)continue;if("StateMachine"===(null!==(i=null!==(s=null===(n=null==t?void 0:t.constructor)||void 0===n?void 0:n.componentName)&&void 0!==s?s:null==t?void 0:t.name)&&void 0!==i?i:"")&&"function"==typeof t.reset)try{t.reset()}catch(t){console.warn("[plugin-state-machine] auto-reset failed:",t)}}}}onDestroy(){this.sceneChangedHandler&&this.game&&this.game.off("sceneChanged",this.sceneChangedHandler),this.sceneChangedHandler=null}}o.systemName="StateMachine",exports.FSM_RESET_SIGNAL=s,exports.FSM_SCENE_SWITCH_SIGNAL=i,exports.StateMachineSystem=o;
@@ -120,6 +120,23 @@ export declare class StateMachine extends Component<StateMachineParams> {
120
120
  * StateMachineSystem 只在 sceneChanged 时 emit `'fsm:scene-switch'` 提醒。
121
121
  */
122
122
  reset(payload?: any): void;
123
+ /**
124
+ * 重发当前状态的 onEnter 信号(不 exit、不改 current、不重新订阅 transitions)。
125
+ *
126
+ * 用于 scene 切换 / restartScene 之后:globalEntities 上的 StateMachine 实例不销毁、
127
+ * 不发生状态转换,所以不会重发 onEnter;但本 scene 重建出的新 controller(如依赖
128
+ * `meta:fsm:enter:PLAYING` 激活的 cannon)需要这个信号才能 active。restartScene
129
+ * 完成后由 GlobalEntitiesManager 对 global StateMachine 调 reenterCurrent(),让新
130
+ * controller 收到 enter 信号(ADR-0017 选项 D)。
131
+ *
132
+ * 与 reset() 区别:reset 回 initial 并清订阅;reenterCurrent 保持当前状态,只补发
133
+ * onEnter(+ signalChange),订阅不动。
134
+ * 与 goto(current, {force}) 区别:force 会先 emit onExit 再重新订阅;reenterCurrent
135
+ * 不 exit、不重订阅(订阅还活着),更轻,适合 scene 切换后补发。
136
+ *
137
+ * 当前没进入任何状态(init 前)时是 no-op。
138
+ */
139
+ reenterCurrent(payload?: any): void;
123
140
  /** reset() 用的 initial state 引用;init 时缓存一次,后续不变 */
124
141
  private initialState;
125
142
  get state(): string;
@@ -145,9 +162,18 @@ export declare class StateMachineSystem extends System<StateMachineSystemParams>
145
162
  static systemName: string;
146
163
  readonly name = "StateMachine";
147
164
  private emitSceneSwitch;
165
+ private autoResetOnSceneSwitch;
148
166
  private sceneChangedHandler;
149
167
  init(params?: StateMachineSystemParams): void;
150
168
  awake(): void;
169
+ /**
170
+ * 遍历 game.gameObjects 找所有 StateMachine Component 调 reset()。
171
+ * 仅在 `autoResetOnSceneSwitch === true` 时被 awake 钩子调用。
172
+ *
173
+ * 注意:walk 失败时 swallow error 不抛(scene 切换 latency 路径不应被
174
+ * 单个 FSM 异常阻断,fsm.reset 内部已有 fail-safe console.warn)。
175
+ */
176
+ private resetAllStateMachines;
151
177
  onDestroy(): void;
152
178
  }
153
179
 
@@ -171,6 +197,20 @@ declare interface StateMachineSystemParams {
171
197
  * 关闭后挂载该 System 与原版空 System 等价。
172
198
  */
173
199
  emitSceneSwitch?: boolean;
200
+ /**
201
+ * 是否在 game `sceneChanged` 时自动对所有 StateMachine 实例调 `reset()`(ADR-0024B)。
202
+ *
203
+ * **默认 false**(向后兼容,与 ADR-0011/0017 "framework 不自动 reset"契约一致)。
204
+ *
205
+ * 设为 true 时,System 在 sceneChanged 后会:
206
+ * 1. 先 emit `'fsm:scene-switch'` 观测信号(保持既有契约)
207
+ * 2. 再 walk 当前 game.gameObjects,找所有 StateMachine Component 调 `reset()`
208
+ *
209
+ * 注意:scene-scoped 实体上的 FSM 会随 scene 销毁,reset 主要影响 globalEntities
210
+ * 上的 FSM。这是 ctx.fsm.attach(BehaviorContext)在 detach 时的 fallback —
211
+ * BehaviorScript 控制更细粒度的 attach handle 时不需要开启 autoReset。
212
+ */
213
+ autoResetOnSceneSwitch?: boolean;
174
214
  }
175
215
 
176
216
  /** 单条迁移规则 */
@@ -165,6 +165,38 @@ let StateMachine = StateMachine_1 = class StateMachine extends Component {
165
165
  };
166
166
  getSignalBus().emit(FSM_RESET_SIGNAL, resetPayload);
167
167
  }
168
+ /**
169
+ * 重发当前状态的 onEnter 信号(不 exit、不改 current、不重新订阅 transitions)。
170
+ *
171
+ * 用于 scene 切换 / restartScene 之后:globalEntities 上的 StateMachine 实例不销毁、
172
+ * 不发生状态转换,所以不会重发 onEnter;但本 scene 重建出的新 controller(如依赖
173
+ * `meta:fsm:enter:PLAYING` 激活的 cannon)需要这个信号才能 active。restartScene
174
+ * 完成后由 GlobalEntitiesManager 对 global StateMachine 调 reenterCurrent(),让新
175
+ * controller 收到 enter 信号(ADR-0017 选项 D)。
176
+ *
177
+ * 与 reset() 区别:reset 回 initial 并清订阅;reenterCurrent 保持当前状态,只补发
178
+ * onEnter(+ signalChange),订阅不动。
179
+ * 与 goto(current, {force}) 区别:force 会先 emit onExit 再重新订阅;reenterCurrent
180
+ * 不 exit、不重订阅(订阅还活着),更轻,适合 scene 切换后补发。
181
+ *
182
+ * 当前没进入任何状态(init 前)时是 no-op。
183
+ */
184
+ reenterCurrent(payload) {
185
+ if (!this.current)
186
+ return;
187
+ const cfg = this.states[this.current];
188
+ if (!cfg)
189
+ return;
190
+ const from = this.current;
191
+ const to = this.current;
192
+ const bus = getSignalBus();
193
+ if (cfg.onEnter) {
194
+ bus.emit(cfg.onEnter, Object.assign({ from, to, reason: 'reenter' }, (payload || {})));
195
+ }
196
+ if (this.signalChange) {
197
+ bus.emit(this.signalChange, { from, to, reason: 'reenter' });
198
+ }
199
+ }
168
200
  get state() {
169
201
  return this.current;
170
202
  }
@@ -247,14 +279,17 @@ class StateMachineSystem extends System {
247
279
  super(...arguments);
248
280
  this.name = 'StateMachine';
249
281
  this.emitSceneSwitch = true;
282
+ this.autoResetOnSceneSwitch = false;
250
283
  this.sceneChangedHandler = null;
251
284
  }
252
285
  init(params) {
253
286
  if ((params === null || params === void 0 ? void 0 : params.emitSceneSwitch) === false)
254
287
  this.emitSceneSwitch = false;
288
+ if ((params === null || params === void 0 ? void 0 : params.autoResetOnSceneSwitch) === true)
289
+ this.autoResetOnSceneSwitch = true;
255
290
  }
256
291
  awake() {
257
- if (!this.emitSceneSwitch)
292
+ if (!this.emitSceneSwitch && !this.autoResetOnSceneSwitch)
258
293
  return;
259
294
  if (!this.game)
260
295
  return;
@@ -264,11 +299,51 @@ class StateMachineSystem extends System {
264
299
  const scene = raw && typeof raw === 'object' && 'scene' in raw
265
300
  ? raw.scene
266
301
  : undefined;
267
- const payload = { scene, raw };
268
- getSignalBus().emit(FSM_SCENE_SWITCH_SIGNAL, payload);
302
+ if (this.emitSceneSwitch) {
303
+ const payload = { scene, raw };
304
+ getSignalBus().emit(FSM_SCENE_SWITCH_SIGNAL, payload);
305
+ }
306
+ if (this.autoResetOnSceneSwitch) {
307
+ this.resetAllStateMachines();
308
+ }
269
309
  };
270
310
  this.game.on('sceneChanged', this.sceneChangedHandler);
271
311
  }
312
+ /**
313
+ * 遍历 game.gameObjects 找所有 StateMachine Component 调 reset()。
314
+ * 仅在 `autoResetOnSceneSwitch === true` 时被 awake 钩子调用。
315
+ *
316
+ * 注意:walk 失败时 swallow error 不抛(scene 切换 latency 路径不应被
317
+ * 单个 FSM 异常阻断,fsm.reset 内部已有 fail-safe console.warn)。
318
+ */
319
+ resetAllStateMachines() {
320
+ var _a, _b, _c, _d, _e;
321
+ if (!this.game)
322
+ return;
323
+ const gameObjects = (_a = this.game.gameObjects) !== null && _a !== void 0 ? _a : [];
324
+ for (const go of gameObjects) {
325
+ if (!go || typeof go !== 'object')
326
+ continue;
327
+ const comps = (_b = go.components) !== null && _b !== void 0 ? _b : [];
328
+ for (const comp of comps) {
329
+ if (!comp)
330
+ continue;
331
+ // duck-typing:同时识别 constructor.componentName 与 instance.name
332
+ const componentName = (_e = (_d = (_c = comp === null || comp === void 0 ? void 0 : comp.constructor) === null || _c === void 0 ? void 0 : _c.componentName) !== null && _d !== void 0 ? _d : comp === null || comp === void 0 ? void 0 : comp.name) !== null && _e !== void 0 ? _e : '';
333
+ if (componentName !== 'StateMachine')
334
+ continue;
335
+ if (typeof comp.reset !== 'function')
336
+ continue;
337
+ try {
338
+ comp.reset();
339
+ }
340
+ catch (err) {
341
+ // eslint-disable-next-line no-console
342
+ console.warn('[plugin-state-machine] auto-reset failed:', err);
343
+ }
344
+ }
345
+ }
346
+ }
272
347
  onDestroy() {
273
348
  if (this.sceneChangedHandler && this.game) {
274
349
  this.game.off('sceneChanged', this.sceneChangedHandler);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eva/plugin-state-machine",
3
- "version": "2.1.0-beta.5",
3
+ "version": "2.1.0-beta.6",
4
4
  "description": "Finite state machine — DSL 声明 states/transitions/timeouts/guards/actions,emit state-change 信号。",
5
5
  "main": "index.js",
6
6
  "module": "dist/plugin-state-machine.esm.js",
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@eva/eva.js": "2.1.0-beta.5",
21
- "@eva/plugin-signal-bus": "2.1.0-beta.5"
20
+ "@eva/eva.js": "2.1.0-beta.6",
21
+ "@eva/plugin-signal-bus": "2.1.0-beta.6"
22
22
  }
23
23
  }