@energy8platform/game-engine 0.7.1 → 0.9.0

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.
@@ -58,10 +58,12 @@ interface StateMachineEvents {
58
58
  * ```
59
59
  */
60
60
  export class StateMachine<TContext = Record<string, unknown>> extends EventEmitter<StateMachineEvents> {
61
+ private static MAX_TRANSITION_DEPTH = 10;
62
+
61
63
  private _states = new Map<string, StateConfig<TContext>>();
62
64
  private _guards = new Map<string, (ctx: TContext) => boolean>();
63
65
  private _current: string | null = null;
64
- private _transitioning = false;
66
+ private _transitionDepth = 0;
65
67
  private _context: TContext;
66
68
 
67
69
  constructor(context: TContext) {
@@ -76,7 +78,7 @@ export class StateMachine<TContext = Record<string, unknown>> extends EventEmitt
76
78
 
77
79
  /** Whether a transition is in progress */
78
80
  get isTransitioning(): boolean {
79
- return this._transitioning;
81
+ return this._transitionDepth > 0;
80
82
  }
81
83
 
82
84
  /** State machine context (shared data) */
@@ -131,9 +133,10 @@ export class StateMachine<TContext = Record<string, unknown>> extends EventEmitt
131
133
  * @returns true if the transition succeeded, false if blocked by a guard
132
134
  */
133
135
  async transition(to: string, data?: unknown): Promise<boolean> {
134
- if (this._transitioning) {
135
- console.warn('[StateMachine] Transition already in progress');
136
- return false;
136
+ if (this._transitionDepth >= StateMachine.MAX_TRANSITION_DEPTH) {
137
+ throw new Error(
138
+ '[StateMachine] Max transition depth exceeded — possible infinite loop',
139
+ );
137
140
  }
138
141
 
139
142
  const from = this._current;
@@ -152,7 +155,7 @@ export class StateMachine<TContext = Record<string, unknown>> extends EventEmitt
152
155
  throw new Error(`[StateMachine] State "${to}" not registered.`);
153
156
  }
154
157
 
155
- this._transitioning = true;
158
+ this._transitionDepth++;
156
159
 
157
160
  try {
158
161
  // Exit current state
@@ -170,7 +173,7 @@ export class StateMachine<TContext = Record<string, unknown>> extends EventEmitt
170
173
  this.emit('error', err instanceof Error ? err : new Error(String(err)));
171
174
  throw err;
172
175
  } finally {
173
- this._transitioning = false;
176
+ this._transitionDepth--;
174
177
  }
175
178
 
176
179
  return true;
@@ -213,7 +216,7 @@ export class StateMachine<TContext = Record<string, unknown>> extends EventEmitt
213
216
  await state?.exit?.(this._context);
214
217
  }
215
218
  this._current = null;
216
- this._transitioning = false;
219
+ this._transitionDepth = 0;
217
220
  }
218
221
 
219
222
  /**
package/src/types.ts CHANGED
@@ -150,6 +150,9 @@ export interface IScene {
150
150
  /** Root display container for this scene */
151
151
  readonly container: Container;
152
152
 
153
+ /** @internal GameApplication reference — set by SceneManager */
154
+ __engineApp?: any;
155
+
153
156
  /** Called when the scene is entered */
154
157
  onEnter?(data?: unknown): Promise<void> | void;
155
158
 
package/src/vite/index.ts CHANGED
@@ -149,6 +149,9 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
149
149
  '@pixi/ui',
150
150
  'yoga-layout',
151
151
  'yoga-layout/load',
152
+ 'react',
153
+ 'react-dom',
154
+ 'react-reconciler',
152
155
  ],
153
156
  ...userVite.resolve,
154
157
  },
@@ -160,6 +163,8 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
160
163
  '@pixi/layout/components',
161
164
  '@pixi/ui',
162
165
  'yoga-layout/load',
166
+ 'react',
167
+ 'react-dom',
163
168
  ],
164
169
  exclude: [
165
170
  'yoga-layout',