@esengine/fsm 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ESEngine Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,500 @@
1
+ import * as _esengine_ecs_framework from '@esengine/ecs-framework';
2
+ import { BlueprintNodeTemplate, INodeExecutor, BlueprintNode, ExecutionResult } from '@esengine/blueprint';
3
+
4
+ /**
5
+ * @zh 状态机接口
6
+ * @en State Machine Interface
7
+ *
8
+ * @zh 提供有限状态机的核心接口
9
+ * @en Provides core interfaces for finite state machine
10
+ */
11
+ /**
12
+ * @zh 状态配置
13
+ * @en State configuration
14
+ */
15
+ interface StateConfig<TState extends string = string, TContext = unknown> {
16
+ /**
17
+ * @zh 状态名称
18
+ * @en State name
19
+ */
20
+ readonly name: TState;
21
+ /**
22
+ * @zh 进入状态时的回调
23
+ * @en Callback when entering state
24
+ */
25
+ onEnter?: (context: TContext, from: TState | null) => void;
26
+ /**
27
+ * @zh 退出状态时的回调
28
+ * @en Callback when exiting state
29
+ */
30
+ onExit?: (context: TContext, to: TState) => void;
31
+ /**
32
+ * @zh 状态更新回调
33
+ * @en State update callback
34
+ */
35
+ onUpdate?: (context: TContext, deltaTime: number) => void;
36
+ /**
37
+ * @zh 状态标签
38
+ * @en State tags
39
+ */
40
+ tags?: string[];
41
+ /**
42
+ * @zh 状态元数据
43
+ * @en State metadata
44
+ */
45
+ metadata?: Record<string, unknown>;
46
+ }
47
+ /**
48
+ * @zh 转换条件函数
49
+ * @en Transition condition function
50
+ */
51
+ type TransitionCondition<TContext = unknown> = (context: TContext) => boolean;
52
+ /**
53
+ * @zh 转换配置
54
+ * @en Transition configuration
55
+ */
56
+ interface TransitionConfig<TState extends string = string, TContext = unknown> {
57
+ /**
58
+ * @zh 源状态
59
+ * @en Source state
60
+ */
61
+ readonly from: TState;
62
+ /**
63
+ * @zh 目标状态
64
+ * @en Target state
65
+ */
66
+ readonly to: TState;
67
+ /**
68
+ * @zh 转换条件
69
+ * @en Transition condition
70
+ */
71
+ condition?: TransitionCondition<TContext>;
72
+ /**
73
+ * @zh 转换优先级(数字越大优先级越高)
74
+ * @en Transition priority (higher number = higher priority)
75
+ */
76
+ priority?: number;
77
+ /**
78
+ * @zh 转换名称(用于调试)
79
+ * @en Transition name (for debugging)
80
+ */
81
+ name?: string;
82
+ }
83
+ /**
84
+ * @zh 状态变更事件
85
+ * @en State change event
86
+ */
87
+ interface StateChangeEvent<TState extends string = string> {
88
+ /**
89
+ * @zh 之前的状态
90
+ * @en Previous state
91
+ */
92
+ readonly from: TState | null;
93
+ /**
94
+ * @zh 当前状态
95
+ * @en Current state
96
+ */
97
+ readonly to: TState;
98
+ /**
99
+ * @zh 时间戳
100
+ * @en Timestamp
101
+ */
102
+ readonly timestamp: number;
103
+ }
104
+ /**
105
+ * @zh 状态变更监听器
106
+ * @en State change listener
107
+ */
108
+ type StateChangeListener<TState extends string = string> = (event: StateChangeEvent<TState>) => void;
109
+ /**
110
+ * @zh 状态机接口
111
+ * @en State machine interface
112
+ *
113
+ * @zh 通用有限状态机,用于角色/AI 状态管理
114
+ * @en Generic finite state machine for character/AI state management
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * type PlayerState = 'idle' | 'walk' | 'run' | 'jump' | 'attack';
119
+ *
120
+ * const fsm = createStateMachine<PlayerState>('idle');
121
+ *
122
+ * fsm.defineState('idle', {
123
+ * onEnter: () => console.log('Entering idle'),
124
+ * onExit: () => console.log('Exiting idle')
125
+ * });
126
+ *
127
+ * fsm.defineTransition('idle', 'walk', () => isMoving);
128
+ * fsm.defineTransition('walk', 'run', () => isRunning);
129
+ *
130
+ * fsm.transition('walk'); // 手动转换
131
+ * fsm.evaluateTransitions(); // 自动评估条件
132
+ * ```
133
+ */
134
+ interface IStateMachine<TState extends string = string, TContext = unknown> {
135
+ /**
136
+ * @zh 当前状态
137
+ * @en Current state
138
+ */
139
+ readonly current: TState;
140
+ /**
141
+ * @zh 之前的状态
142
+ * @en Previous state
143
+ */
144
+ readonly previous: TState | null;
145
+ /**
146
+ * @zh 状态机上下文
147
+ * @en State machine context
148
+ */
149
+ readonly context: TContext;
150
+ /**
151
+ * @zh 是否正在转换中
152
+ * @en Whether a transition is in progress
153
+ */
154
+ readonly isTransitioning: boolean;
155
+ /**
156
+ * @zh 当前状态持续时间(毫秒)
157
+ * @en Current state duration in milliseconds
158
+ */
159
+ readonly currentStateDuration: number;
160
+ /**
161
+ * @zh 定义状态
162
+ * @en Define state
163
+ *
164
+ * @param state - @zh 状态名称 @en State name
165
+ * @param config - @zh 状态配置 @en State configuration
166
+ */
167
+ defineState(state: TState, config?: Partial<StateConfig<TState, TContext>>): void;
168
+ /**
169
+ * @zh 检查状态是否已定义
170
+ * @en Check if state is defined
171
+ *
172
+ * @param state - @zh 状态名称 @en State name
173
+ */
174
+ hasState(state: TState): boolean;
175
+ /**
176
+ * @zh 获取状态配置
177
+ * @en Get state configuration
178
+ *
179
+ * @param state - @zh 状态名称 @en State name
180
+ */
181
+ getStateConfig(state: TState): StateConfig<TState, TContext> | undefined;
182
+ /**
183
+ * @zh 获取所有定义的状态
184
+ * @en Get all defined states
185
+ */
186
+ getStates(): TState[];
187
+ /**
188
+ * @zh 定义转换
189
+ * @en Define transition
190
+ *
191
+ * @param from - @zh 源状态 @en Source state
192
+ * @param to - @zh 目标状态 @en Target state
193
+ * @param condition - @zh 转换条件 @en Transition condition
194
+ * @param priority - @zh 优先级 @en Priority
195
+ */
196
+ defineTransition(from: TState, to: TState, condition?: TransitionCondition<TContext>, priority?: number): void;
197
+ /**
198
+ * @zh 移除转换
199
+ * @en Remove transition
200
+ *
201
+ * @param from - @zh 源状态 @en Source state
202
+ * @param to - @zh 目标状态 @en Target state
203
+ */
204
+ removeTransition(from: TState, to: TState): void;
205
+ /**
206
+ * @zh 获取从指定状态可用的转换
207
+ * @en Get available transitions from state
208
+ *
209
+ * @param from - @zh 源状态 @en Source state
210
+ */
211
+ getTransitionsFrom(from: TState): TransitionConfig<TState, TContext>[];
212
+ /**
213
+ * @zh 检查是否可以转换到目标状态
214
+ * @en Check if can transition to target state
215
+ *
216
+ * @param to - @zh 目标状态 @en Target state
217
+ */
218
+ canTransition(to: TState): boolean;
219
+ /**
220
+ * @zh 转换到目标状态
221
+ * @en Transition to target state
222
+ *
223
+ * @param to - @zh 目标状态 @en Target state
224
+ * @param force - @zh 强制转换(忽略条件)@en Force transition (ignore condition)
225
+ * @returns @zh 是否成功 @en Whether successful
226
+ */
227
+ transition(to: TState, force?: boolean): boolean;
228
+ /**
229
+ * @zh 评估并执行满足条件的转换
230
+ * @en Evaluate and execute transitions that meet conditions
231
+ *
232
+ * @returns @zh 是否发生转换 @en Whether a transition occurred
233
+ */
234
+ evaluateTransitions(): boolean;
235
+ /**
236
+ * @zh 更新状态机
237
+ * @en Update state machine
238
+ *
239
+ * @param deltaTime - @zh 增量时间(毫秒)@en Delta time in milliseconds
240
+ */
241
+ update(deltaTime: number): void;
242
+ /**
243
+ * @zh 重置状态机到初始状态
244
+ * @en Reset state machine to initial state
245
+ *
246
+ * @param initialState - @zh 初始状态 @en Initial state
247
+ */
248
+ reset(initialState?: TState): void;
249
+ /**
250
+ * @zh 监听状态进入事件
251
+ * @en Listen to state enter event
252
+ *
253
+ * @param state - @zh 状态名称 @en State name
254
+ * @param callback - @zh 回调函数 @en Callback function
255
+ */
256
+ onEnter(state: TState, callback: (from: TState | null) => void): () => void;
257
+ /**
258
+ * @zh 监听状态退出事件
259
+ * @en Listen to state exit event
260
+ *
261
+ * @param state - @zh 状态名称 @en State name
262
+ * @param callback - @zh 回调函数 @en Callback function
263
+ */
264
+ onExit(state: TState, callback: (to: TState) => void): () => void;
265
+ /**
266
+ * @zh 监听任意状态变更
267
+ * @en Listen to any state change
268
+ *
269
+ * @param callback - @zh 回调函数 @en Callback function
270
+ */
271
+ onChange(callback: StateChangeListener<TState>): () => void;
272
+ /**
273
+ * @zh 获取状态历史
274
+ * @en Get state history
275
+ */
276
+ getHistory(): StateChangeEvent<TState>[];
277
+ /**
278
+ * @zh 清除历史
279
+ * @en Clear history
280
+ */
281
+ clearHistory(): void;
282
+ }
283
+
284
+ /**
285
+ * @zh 状态机实现
286
+ * @en State Machine Implementation
287
+ *
288
+ * @zh 提供有限状态机的默认实现
289
+ * @en Provides default implementation for finite state machine
290
+ */
291
+
292
+ /**
293
+ * @zh 状态机配置选项
294
+ * @en State machine configuration options
295
+ */
296
+ interface StateMachineOptions<TContext = unknown> {
297
+ /**
298
+ * @zh 上下文对象
299
+ * @en Context object
300
+ */
301
+ context?: TContext;
302
+ /**
303
+ * @zh 最大历史记录数量
304
+ * @en Maximum history size
305
+ */
306
+ maxHistorySize?: number;
307
+ /**
308
+ * @zh 是否启用历史记录
309
+ * @en Whether to enable history
310
+ */
311
+ enableHistory?: boolean;
312
+ }
313
+ /**
314
+ * @zh 状态机实现
315
+ * @en State machine implementation
316
+ */
317
+ declare class StateMachine<TState extends string = string, TContext = unknown> implements IStateMachine<TState, TContext> {
318
+ private _current;
319
+ private _previous;
320
+ private _context;
321
+ private _isTransitioning;
322
+ private _stateStartTime;
323
+ private states;
324
+ private transitions;
325
+ private enterListeners;
326
+ private exitListeners;
327
+ private changeListeners;
328
+ private history;
329
+ private maxHistorySize;
330
+ private enableHistory;
331
+ constructor(initialState: TState, options?: StateMachineOptions<TContext>);
332
+ get current(): TState;
333
+ get previous(): TState | null;
334
+ get context(): TContext;
335
+ get isTransitioning(): boolean;
336
+ get currentStateDuration(): number;
337
+ defineState(state: TState, config?: Partial<StateConfig<TState, TContext>>): void;
338
+ hasState(state: TState): boolean;
339
+ getStateConfig(state: TState): StateConfig<TState, TContext> | undefined;
340
+ getStates(): TState[];
341
+ defineTransition(from: TState, to: TState, condition?: TransitionCondition<TContext>, priority?: number): void;
342
+ removeTransition(from: TState, to: TState): void;
343
+ getTransitionsFrom(from: TState): TransitionConfig<TState, TContext>[];
344
+ canTransition(to: TState): boolean;
345
+ transition(to: TState, force?: boolean): boolean;
346
+ evaluateTransitions(): boolean;
347
+ private performTransition;
348
+ update(deltaTime: number): void;
349
+ reset(initialState?: TState): void;
350
+ onEnter(state: TState, callback: (from: TState | null) => void): () => void;
351
+ onExit(state: TState, callback: (to: TState) => void): () => void;
352
+ onChange(callback: StateChangeListener<TState>): () => void;
353
+ getHistory(): StateChangeEvent<TState>[];
354
+ clearHistory(): void;
355
+ /**
356
+ * @zh 获取状态机的调试信息
357
+ * @en Get debug info for the state machine
358
+ */
359
+ getDebugInfo(): {
360
+ current: TState;
361
+ previous: TState | null;
362
+ duration: number;
363
+ stateCount: number;
364
+ transitionCount: number;
365
+ historySize: number;
366
+ };
367
+ }
368
+ /**
369
+ * @zh 创建状态机
370
+ * @en Create state machine
371
+ *
372
+ * @param initialState - @zh 初始状态 @en Initial state
373
+ * @param options - @zh 配置选项 @en Configuration options
374
+ * @returns @zh 状态机实例 @en State machine instance
375
+ */
376
+ declare function createStateMachine<TState extends string = string, TContext = unknown>(initialState: TState, options?: StateMachineOptions<TContext>): IStateMachine<TState, TContext>;
377
+
378
+ /**
379
+ * @zh 状态机服务令牌
380
+ * @en State machine service token
381
+ *
382
+ * @zh 用于注入状态机服务
383
+ * @en Used for injecting state machine service
384
+ */
385
+ declare const StateMachineToken: _esengine_ecs_framework.ServiceToken<IStateMachine<string, unknown>>;
386
+
387
+ /**
388
+ * @zh 状态机蓝图节点
389
+ * @en State Machine Blueprint Nodes
390
+ *
391
+ * @zh 提供状态机功能的蓝图节点
392
+ * @en Provides blueprint nodes for state machine functionality
393
+ */
394
+
395
+ /**
396
+ * @zh GetCurrentState 节点模板
397
+ * @en GetCurrentState node template
398
+ */
399
+ declare const GetCurrentStateTemplate: BlueprintNodeTemplate;
400
+ /**
401
+ * @zh GetCurrentState 节点执行器
402
+ * @en GetCurrentState node executor
403
+ */
404
+ declare class GetCurrentStateExecutor implements INodeExecutor {
405
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
406
+ }
407
+ /**
408
+ * @zh TransitionTo 节点模板
409
+ * @en TransitionTo node template
410
+ */
411
+ declare const TransitionToTemplate: BlueprintNodeTemplate;
412
+ /**
413
+ * @zh TransitionTo 节点执行器
414
+ * @en TransitionTo node executor
415
+ */
416
+ declare class TransitionToExecutor implements INodeExecutor {
417
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
418
+ }
419
+ /**
420
+ * @zh CanTransition 节点模板
421
+ * @en CanTransition node template
422
+ */
423
+ declare const CanTransitionTemplate: BlueprintNodeTemplate;
424
+ /**
425
+ * @zh CanTransition 节点执行器
426
+ * @en CanTransition node executor
427
+ */
428
+ declare class CanTransitionExecutor implements INodeExecutor {
429
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
430
+ }
431
+ /**
432
+ * @zh IsInState 节点模板
433
+ * @en IsInState node template
434
+ */
435
+ declare const IsInStateTemplate: BlueprintNodeTemplate;
436
+ /**
437
+ * @zh IsInState 节点执行器
438
+ * @en IsInState node executor
439
+ */
440
+ declare class IsInStateExecutor implements INodeExecutor {
441
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
442
+ }
443
+ /**
444
+ * @zh WasInState 节点模板
445
+ * @en WasInState node template
446
+ */
447
+ declare const WasInStateTemplate: BlueprintNodeTemplate;
448
+ /**
449
+ * @zh WasInState 节点执行器
450
+ * @en WasInState node executor
451
+ */
452
+ declare class WasInStateExecutor implements INodeExecutor {
453
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
454
+ }
455
+ /**
456
+ * @zh GetStateDuration 节点模板
457
+ * @en GetStateDuration node template
458
+ */
459
+ declare const GetStateDurationTemplate: BlueprintNodeTemplate;
460
+ /**
461
+ * @zh GetStateDuration 节点执行器
462
+ * @en GetStateDuration node executor
463
+ */
464
+ declare class GetStateDurationExecutor implements INodeExecutor {
465
+ execute(_node: BlueprintNode, context: unknown): ExecutionResult;
466
+ }
467
+ /**
468
+ * @zh EvaluateTransitions 节点模板
469
+ * @en EvaluateTransitions node template
470
+ */
471
+ declare const EvaluateTransitionsTemplate: BlueprintNodeTemplate;
472
+ /**
473
+ * @zh EvaluateTransitions 节点执行器
474
+ * @en EvaluateTransitions node executor
475
+ */
476
+ declare class EvaluateTransitionsExecutor implements INodeExecutor {
477
+ execute(_node: BlueprintNode, context: unknown): ExecutionResult;
478
+ }
479
+ /**
480
+ * @zh ResetStateMachine 节点模板
481
+ * @en ResetStateMachine node template
482
+ */
483
+ declare const ResetStateMachineTemplate: BlueprintNodeTemplate;
484
+ /**
485
+ * @zh ResetStateMachine 节点执行器
486
+ * @en ResetStateMachine node executor
487
+ */
488
+ declare class ResetStateMachineExecutor implements INodeExecutor {
489
+ execute(node: BlueprintNode, context: unknown): ExecutionResult;
490
+ }
491
+ /**
492
+ * @zh 状态机节点定义
493
+ * @en State machine node definitions
494
+ */
495
+ declare const StateMachineNodeDefinitions: {
496
+ template: BlueprintNodeTemplate;
497
+ executor: GetCurrentStateExecutor;
498
+ }[];
499
+
500
+ export { CanTransitionExecutor, CanTransitionTemplate, EvaluateTransitionsExecutor, EvaluateTransitionsTemplate, GetCurrentStateExecutor, GetCurrentStateTemplate, GetStateDurationExecutor, GetStateDurationTemplate, type IStateMachine, IsInStateExecutor, IsInStateTemplate, ResetStateMachineExecutor, ResetStateMachineTemplate, type StateChangeEvent, type StateChangeListener, type StateConfig, StateMachine, StateMachineNodeDefinitions, type StateMachineOptions, StateMachineToken, type TransitionCondition, type TransitionConfig, TransitionToExecutor, TransitionToTemplate, WasInStateExecutor, WasInStateTemplate, createStateMachine };