@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 +21 -0
- package/dist/index.d.ts +500 -0
- package/dist/index.js +772 -0
- package/dist/index.js.map +1 -0
- package/module.json +23 -0
- package/package.json +40 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
|
|
6
|
+
// src/StateMachine.ts
|
|
7
|
+
var _StateMachine = class _StateMachine {
|
|
8
|
+
constructor(initialState, options = {}) {
|
|
9
|
+
__publicField(this, "_current");
|
|
10
|
+
__publicField(this, "_previous", null);
|
|
11
|
+
__publicField(this, "_context");
|
|
12
|
+
__publicField(this, "_isTransitioning", false);
|
|
13
|
+
__publicField(this, "_stateStartTime", 0);
|
|
14
|
+
__publicField(this, "states", /* @__PURE__ */ new Map());
|
|
15
|
+
__publicField(this, "transitions", /* @__PURE__ */ new Map());
|
|
16
|
+
__publicField(this, "enterListeners", /* @__PURE__ */ new Map());
|
|
17
|
+
__publicField(this, "exitListeners", /* @__PURE__ */ new Map());
|
|
18
|
+
__publicField(this, "changeListeners", /* @__PURE__ */ new Set());
|
|
19
|
+
__publicField(this, "history", []);
|
|
20
|
+
__publicField(this, "maxHistorySize");
|
|
21
|
+
__publicField(this, "enableHistory");
|
|
22
|
+
this._current = initialState;
|
|
23
|
+
this._context = options.context ?? {};
|
|
24
|
+
this.maxHistorySize = options.maxHistorySize ?? 100;
|
|
25
|
+
this.enableHistory = options.enableHistory ?? true;
|
|
26
|
+
this._stateStartTime = Date.now();
|
|
27
|
+
this.defineState(initialState);
|
|
28
|
+
}
|
|
29
|
+
// =========================================================================
|
|
30
|
+
// 属性 | Properties
|
|
31
|
+
// =========================================================================
|
|
32
|
+
get current() {
|
|
33
|
+
return this._current;
|
|
34
|
+
}
|
|
35
|
+
get previous() {
|
|
36
|
+
return this._previous;
|
|
37
|
+
}
|
|
38
|
+
get context() {
|
|
39
|
+
return this._context;
|
|
40
|
+
}
|
|
41
|
+
get isTransitioning() {
|
|
42
|
+
return this._isTransitioning;
|
|
43
|
+
}
|
|
44
|
+
get currentStateDuration() {
|
|
45
|
+
return Date.now() - this._stateStartTime;
|
|
46
|
+
}
|
|
47
|
+
// =========================================================================
|
|
48
|
+
// 状态定义 | State Definition
|
|
49
|
+
// =========================================================================
|
|
50
|
+
defineState(state, config) {
|
|
51
|
+
const stateConfig = {
|
|
52
|
+
name: state,
|
|
53
|
+
...config
|
|
54
|
+
};
|
|
55
|
+
this.states.set(state, stateConfig);
|
|
56
|
+
}
|
|
57
|
+
hasState(state) {
|
|
58
|
+
return this.states.has(state);
|
|
59
|
+
}
|
|
60
|
+
getStateConfig(state) {
|
|
61
|
+
return this.states.get(state);
|
|
62
|
+
}
|
|
63
|
+
getStates() {
|
|
64
|
+
return Array.from(this.states.keys());
|
|
65
|
+
}
|
|
66
|
+
// =========================================================================
|
|
67
|
+
// 转换定义 | Transition Definition
|
|
68
|
+
// =========================================================================
|
|
69
|
+
defineTransition(from, to, condition, priority = 0) {
|
|
70
|
+
if (!this.transitions.has(from)) {
|
|
71
|
+
this.transitions.set(from, []);
|
|
72
|
+
}
|
|
73
|
+
const transitions = this.transitions.get(from);
|
|
74
|
+
const existingIndex = transitions.findIndex((t) => t.to === to);
|
|
75
|
+
if (existingIndex >= 0) {
|
|
76
|
+
transitions.splice(existingIndex, 1);
|
|
77
|
+
}
|
|
78
|
+
transitions.push({
|
|
79
|
+
from,
|
|
80
|
+
to,
|
|
81
|
+
condition,
|
|
82
|
+
priority
|
|
83
|
+
});
|
|
84
|
+
transitions.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
85
|
+
}
|
|
86
|
+
removeTransition(from, to) {
|
|
87
|
+
const transitions = this.transitions.get(from);
|
|
88
|
+
if (transitions) {
|
|
89
|
+
const index = transitions.findIndex((t) => t.to === to);
|
|
90
|
+
if (index >= 0) {
|
|
91
|
+
transitions.splice(index, 1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
getTransitionsFrom(from) {
|
|
96
|
+
return this.transitions.get(from) ?? [];
|
|
97
|
+
}
|
|
98
|
+
// =========================================================================
|
|
99
|
+
// 转换操作 | Transition Operations
|
|
100
|
+
// =========================================================================
|
|
101
|
+
canTransition(to) {
|
|
102
|
+
if (this._isTransitioning) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (this._current === to) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const transitions = this.transitions.get(this._current);
|
|
109
|
+
if (!transitions) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
const transition = transitions.find((t) => t.to === to);
|
|
113
|
+
if (!transition) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (transition.condition) {
|
|
117
|
+
return transition.condition(this._context);
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
transition(to, force = false) {
|
|
122
|
+
if (this._isTransitioning) {
|
|
123
|
+
console.warn("StateMachine: Cannot transition while already transitioning");
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
if (this._current === to) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
if (!force && !this.canTransition(to)) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
this.performTransition(to);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
evaluateTransitions() {
|
|
136
|
+
if (this._isTransitioning) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
const transitions = this.transitions.get(this._current);
|
|
140
|
+
if (!transitions || transitions.length === 0) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
for (const transition of transitions) {
|
|
144
|
+
if (!transition.condition || transition.condition(this._context)) {
|
|
145
|
+
this.performTransition(transition.to);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
performTransition(to) {
|
|
152
|
+
this._isTransitioning = true;
|
|
153
|
+
const from = this._current;
|
|
154
|
+
const currentConfig = this.states.get(from);
|
|
155
|
+
if (currentConfig?.onExit) {
|
|
156
|
+
try {
|
|
157
|
+
currentConfig.onExit(this._context, to);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error(`StateMachine: Error in onExit for state '${from}':`, error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const exitListeners = this.exitListeners.get(from);
|
|
163
|
+
if (exitListeners) {
|
|
164
|
+
for (const listener of exitListeners) {
|
|
165
|
+
try {
|
|
166
|
+
listener(to);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error(`StateMachine: Error in exit listener for state '${from}':`, error);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
this._previous = from;
|
|
173
|
+
this._current = to;
|
|
174
|
+
this._stateStartTime = Date.now();
|
|
175
|
+
if (this.enableHistory) {
|
|
176
|
+
const event = {
|
|
177
|
+
from,
|
|
178
|
+
to,
|
|
179
|
+
timestamp: this._stateStartTime
|
|
180
|
+
};
|
|
181
|
+
this.history.push(event);
|
|
182
|
+
if (this.history.length > this.maxHistorySize) {
|
|
183
|
+
this.history.shift();
|
|
184
|
+
}
|
|
185
|
+
for (const listener of this.changeListeners) {
|
|
186
|
+
try {
|
|
187
|
+
listener(event);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.error("StateMachine: Error in change listener:", error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const newConfig = this.states.get(to);
|
|
194
|
+
if (newConfig?.onEnter) {
|
|
195
|
+
try {
|
|
196
|
+
newConfig.onEnter(this._context, from);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`StateMachine: Error in onEnter for state '${to}':`, error);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const enterListeners = this.enterListeners.get(to);
|
|
202
|
+
if (enterListeners) {
|
|
203
|
+
for (const listener of enterListeners) {
|
|
204
|
+
try {
|
|
205
|
+
listener(from);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.error(`StateMachine: Error in enter listener for state '${to}':`, error);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
this._isTransitioning = false;
|
|
212
|
+
}
|
|
213
|
+
// =========================================================================
|
|
214
|
+
// 生命周期 | Lifecycle
|
|
215
|
+
// =========================================================================
|
|
216
|
+
update(deltaTime) {
|
|
217
|
+
const config = this.states.get(this._current);
|
|
218
|
+
if (config?.onUpdate) {
|
|
219
|
+
try {
|
|
220
|
+
config.onUpdate(this._context, deltaTime);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error(`StateMachine: Error in onUpdate for state '${this._current}':`, error);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
reset(initialState) {
|
|
227
|
+
const targetState = initialState ?? this._current;
|
|
228
|
+
this._previous = null;
|
|
229
|
+
this._current = targetState;
|
|
230
|
+
this._stateStartTime = Date.now();
|
|
231
|
+
this._isTransitioning = false;
|
|
232
|
+
this.clearHistory();
|
|
233
|
+
}
|
|
234
|
+
// =========================================================================
|
|
235
|
+
// 事件监听 | Event Listening
|
|
236
|
+
// =========================================================================
|
|
237
|
+
onEnter(state, callback) {
|
|
238
|
+
if (!this.enterListeners.has(state)) {
|
|
239
|
+
this.enterListeners.set(state, /* @__PURE__ */ new Set());
|
|
240
|
+
}
|
|
241
|
+
this.enterListeners.get(state).add(callback);
|
|
242
|
+
return () => {
|
|
243
|
+
this.enterListeners.get(state)?.delete(callback);
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
onExit(state, callback) {
|
|
247
|
+
if (!this.exitListeners.has(state)) {
|
|
248
|
+
this.exitListeners.set(state, /* @__PURE__ */ new Set());
|
|
249
|
+
}
|
|
250
|
+
this.exitListeners.get(state).add(callback);
|
|
251
|
+
return () => {
|
|
252
|
+
this.exitListeners.get(state)?.delete(callback);
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
onChange(callback) {
|
|
256
|
+
this.changeListeners.add(callback);
|
|
257
|
+
return () => {
|
|
258
|
+
this.changeListeners.delete(callback);
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
// =========================================================================
|
|
262
|
+
// 调试 | Debug
|
|
263
|
+
// =========================================================================
|
|
264
|
+
getHistory() {
|
|
265
|
+
return [
|
|
266
|
+
...this.history
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
clearHistory() {
|
|
270
|
+
this.history = [];
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* @zh 获取状态机的调试信息
|
|
274
|
+
* @en Get debug info for the state machine
|
|
275
|
+
*/
|
|
276
|
+
getDebugInfo() {
|
|
277
|
+
let transitionCount = 0;
|
|
278
|
+
for (const transitions of this.transitions.values()) {
|
|
279
|
+
transitionCount += transitions.length;
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
current: this._current,
|
|
283
|
+
previous: this._previous,
|
|
284
|
+
duration: this.currentStateDuration,
|
|
285
|
+
stateCount: this.states.size,
|
|
286
|
+
transitionCount,
|
|
287
|
+
historySize: this.history.length
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
__name(_StateMachine, "StateMachine");
|
|
292
|
+
var StateMachine = _StateMachine;
|
|
293
|
+
function createStateMachine(initialState, options) {
|
|
294
|
+
return new StateMachine(initialState, options);
|
|
295
|
+
}
|
|
296
|
+
__name(createStateMachine, "createStateMachine");
|
|
297
|
+
|
|
298
|
+
// src/tokens.ts
|
|
299
|
+
import { createServiceToken } from "@esengine/ecs-framework";
|
|
300
|
+
var StateMachineToken = createServiceToken("stateMachine");
|
|
301
|
+
|
|
302
|
+
// src/nodes/StateMachineNodes.ts
|
|
303
|
+
var GetCurrentStateTemplate = {
|
|
304
|
+
type: "GetCurrentState",
|
|
305
|
+
title: "Get Current State",
|
|
306
|
+
category: "logic",
|
|
307
|
+
description: "Get current state of the state machine / \u83B7\u53D6\u72B6\u6001\u673A\u5F53\u524D\u72B6\u6001",
|
|
308
|
+
keywords: [
|
|
309
|
+
"fsm",
|
|
310
|
+
"state",
|
|
311
|
+
"current",
|
|
312
|
+
"get"
|
|
313
|
+
],
|
|
314
|
+
menuPath: [
|
|
315
|
+
"State Machine",
|
|
316
|
+
"Get Current State"
|
|
317
|
+
],
|
|
318
|
+
isPure: true,
|
|
319
|
+
inputs: [],
|
|
320
|
+
outputs: [
|
|
321
|
+
{
|
|
322
|
+
name: "state",
|
|
323
|
+
displayName: "State",
|
|
324
|
+
type: "string"
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: "previous",
|
|
328
|
+
displayName: "Previous",
|
|
329
|
+
type: "string"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "duration",
|
|
333
|
+
displayName: "Duration (ms)",
|
|
334
|
+
type: "float"
|
|
335
|
+
}
|
|
336
|
+
],
|
|
337
|
+
color: "#8b5a8b"
|
|
338
|
+
};
|
|
339
|
+
var _GetCurrentStateExecutor = class _GetCurrentStateExecutor {
|
|
340
|
+
execute(node, context) {
|
|
341
|
+
const ctx = context;
|
|
342
|
+
const fsm = ctx.stateMachine;
|
|
343
|
+
return {
|
|
344
|
+
outputs: {
|
|
345
|
+
state: fsm?.current ?? "",
|
|
346
|
+
previous: fsm?.previous ?? "",
|
|
347
|
+
duration: fsm?.currentStateDuration ?? 0
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
__name(_GetCurrentStateExecutor, "GetCurrentStateExecutor");
|
|
353
|
+
var GetCurrentStateExecutor = _GetCurrentStateExecutor;
|
|
354
|
+
var TransitionToTemplate = {
|
|
355
|
+
type: "TransitionTo",
|
|
356
|
+
title: "Transition To",
|
|
357
|
+
category: "logic",
|
|
358
|
+
description: "Transition to a new state / \u8F6C\u6362\u5230\u65B0\u72B6\u6001",
|
|
359
|
+
keywords: [
|
|
360
|
+
"fsm",
|
|
361
|
+
"state",
|
|
362
|
+
"transition",
|
|
363
|
+
"change"
|
|
364
|
+
],
|
|
365
|
+
menuPath: [
|
|
366
|
+
"State Machine",
|
|
367
|
+
"Transition To"
|
|
368
|
+
],
|
|
369
|
+
isPure: false,
|
|
370
|
+
inputs: [
|
|
371
|
+
{
|
|
372
|
+
name: "exec",
|
|
373
|
+
displayName: "",
|
|
374
|
+
type: "exec"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "state",
|
|
378
|
+
displayName: "Target State",
|
|
379
|
+
type: "string",
|
|
380
|
+
defaultValue: ""
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: "force",
|
|
384
|
+
displayName: "Force",
|
|
385
|
+
type: "bool",
|
|
386
|
+
defaultValue: false
|
|
387
|
+
}
|
|
388
|
+
],
|
|
389
|
+
outputs: [
|
|
390
|
+
{
|
|
391
|
+
name: "exec",
|
|
392
|
+
displayName: "",
|
|
393
|
+
type: "exec"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "success",
|
|
397
|
+
displayName: "Success",
|
|
398
|
+
type: "bool"
|
|
399
|
+
}
|
|
400
|
+
],
|
|
401
|
+
color: "#8b5a8b"
|
|
402
|
+
};
|
|
403
|
+
var _TransitionToExecutor = class _TransitionToExecutor {
|
|
404
|
+
execute(node, context) {
|
|
405
|
+
const ctx = context;
|
|
406
|
+
const state = ctx.evaluateInput(node.id, "state", "");
|
|
407
|
+
const force = ctx.evaluateInput(node.id, "force", false);
|
|
408
|
+
let success = false;
|
|
409
|
+
if (state && ctx.stateMachine) {
|
|
410
|
+
success = ctx.stateMachine.transition(state, force);
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
outputs: {
|
|
414
|
+
success
|
|
415
|
+
},
|
|
416
|
+
nextExec: "exec"
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
__name(_TransitionToExecutor, "TransitionToExecutor");
|
|
421
|
+
var TransitionToExecutor = _TransitionToExecutor;
|
|
422
|
+
var CanTransitionTemplate = {
|
|
423
|
+
type: "CanTransition",
|
|
424
|
+
title: "Can Transition",
|
|
425
|
+
category: "logic",
|
|
426
|
+
description: "Check if can transition to state / \u68C0\u67E5\u662F\u5426\u53EF\u4EE5\u8F6C\u6362\u5230\u72B6\u6001",
|
|
427
|
+
keywords: [
|
|
428
|
+
"fsm",
|
|
429
|
+
"state",
|
|
430
|
+
"transition",
|
|
431
|
+
"can",
|
|
432
|
+
"check"
|
|
433
|
+
],
|
|
434
|
+
menuPath: [
|
|
435
|
+
"State Machine",
|
|
436
|
+
"Can Transition"
|
|
437
|
+
],
|
|
438
|
+
isPure: true,
|
|
439
|
+
inputs: [
|
|
440
|
+
{
|
|
441
|
+
name: "state",
|
|
442
|
+
displayName: "Target State",
|
|
443
|
+
type: "string",
|
|
444
|
+
defaultValue: ""
|
|
445
|
+
}
|
|
446
|
+
],
|
|
447
|
+
outputs: [
|
|
448
|
+
{
|
|
449
|
+
name: "canTransition",
|
|
450
|
+
displayName: "Can Transition",
|
|
451
|
+
type: "bool"
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
color: "#8b5a8b"
|
|
455
|
+
};
|
|
456
|
+
var _CanTransitionExecutor = class _CanTransitionExecutor {
|
|
457
|
+
execute(node, context) {
|
|
458
|
+
const ctx = context;
|
|
459
|
+
const state = ctx.evaluateInput(node.id, "state", "");
|
|
460
|
+
const canTransition = state ? ctx.stateMachine?.canTransition(state) ?? false : false;
|
|
461
|
+
return {
|
|
462
|
+
outputs: {
|
|
463
|
+
canTransition
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
__name(_CanTransitionExecutor, "CanTransitionExecutor");
|
|
469
|
+
var CanTransitionExecutor = _CanTransitionExecutor;
|
|
470
|
+
var IsInStateTemplate = {
|
|
471
|
+
type: "IsInState",
|
|
472
|
+
title: "Is In State",
|
|
473
|
+
category: "logic",
|
|
474
|
+
description: "Check if currently in a specific state / \u68C0\u67E5\u662F\u5426\u5904\u4E8E\u7279\u5B9A\u72B6\u6001",
|
|
475
|
+
keywords: [
|
|
476
|
+
"fsm",
|
|
477
|
+
"state",
|
|
478
|
+
"is",
|
|
479
|
+
"check",
|
|
480
|
+
"current"
|
|
481
|
+
],
|
|
482
|
+
menuPath: [
|
|
483
|
+
"State Machine",
|
|
484
|
+
"Is In State"
|
|
485
|
+
],
|
|
486
|
+
isPure: true,
|
|
487
|
+
inputs: [
|
|
488
|
+
{
|
|
489
|
+
name: "state",
|
|
490
|
+
displayName: "State",
|
|
491
|
+
type: "string",
|
|
492
|
+
defaultValue: ""
|
|
493
|
+
}
|
|
494
|
+
],
|
|
495
|
+
outputs: [
|
|
496
|
+
{
|
|
497
|
+
name: "isInState",
|
|
498
|
+
displayName: "Is In State",
|
|
499
|
+
type: "bool"
|
|
500
|
+
}
|
|
501
|
+
],
|
|
502
|
+
color: "#8b5a8b"
|
|
503
|
+
};
|
|
504
|
+
var _IsInStateExecutor = class _IsInStateExecutor {
|
|
505
|
+
execute(node, context) {
|
|
506
|
+
const ctx = context;
|
|
507
|
+
const state = ctx.evaluateInput(node.id, "state", "");
|
|
508
|
+
const isInState = state ? ctx.stateMachine?.current === state : false;
|
|
509
|
+
return {
|
|
510
|
+
outputs: {
|
|
511
|
+
isInState
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
__name(_IsInStateExecutor, "IsInStateExecutor");
|
|
517
|
+
var IsInStateExecutor = _IsInStateExecutor;
|
|
518
|
+
var WasInStateTemplate = {
|
|
519
|
+
type: "WasInState",
|
|
520
|
+
title: "Was In State",
|
|
521
|
+
category: "logic",
|
|
522
|
+
description: "Check if was previously in a specific state / \u68C0\u67E5\u4E4B\u524D\u662F\u5426\u5904\u4E8E\u7279\u5B9A\u72B6\u6001",
|
|
523
|
+
keywords: [
|
|
524
|
+
"fsm",
|
|
525
|
+
"state",
|
|
526
|
+
"was",
|
|
527
|
+
"previous",
|
|
528
|
+
"check"
|
|
529
|
+
],
|
|
530
|
+
menuPath: [
|
|
531
|
+
"State Machine",
|
|
532
|
+
"Was In State"
|
|
533
|
+
],
|
|
534
|
+
isPure: true,
|
|
535
|
+
inputs: [
|
|
536
|
+
{
|
|
537
|
+
name: "state",
|
|
538
|
+
displayName: "State",
|
|
539
|
+
type: "string",
|
|
540
|
+
defaultValue: ""
|
|
541
|
+
}
|
|
542
|
+
],
|
|
543
|
+
outputs: [
|
|
544
|
+
{
|
|
545
|
+
name: "wasInState",
|
|
546
|
+
displayName: "Was In State",
|
|
547
|
+
type: "bool"
|
|
548
|
+
}
|
|
549
|
+
],
|
|
550
|
+
color: "#8b5a8b"
|
|
551
|
+
};
|
|
552
|
+
var _WasInStateExecutor = class _WasInStateExecutor {
|
|
553
|
+
execute(node, context) {
|
|
554
|
+
const ctx = context;
|
|
555
|
+
const state = ctx.evaluateInput(node.id, "state", "");
|
|
556
|
+
const wasInState = state ? ctx.stateMachine?.previous === state : false;
|
|
557
|
+
return {
|
|
558
|
+
outputs: {
|
|
559
|
+
wasInState
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
__name(_WasInStateExecutor, "WasInStateExecutor");
|
|
565
|
+
var WasInStateExecutor = _WasInStateExecutor;
|
|
566
|
+
var GetStateDurationTemplate = {
|
|
567
|
+
type: "GetStateDuration",
|
|
568
|
+
title: "Get State Duration",
|
|
569
|
+
category: "logic",
|
|
570
|
+
description: "Get how long current state has been active / \u83B7\u53D6\u5F53\u524D\u72B6\u6001\u6301\u7EED\u65F6\u95F4",
|
|
571
|
+
keywords: [
|
|
572
|
+
"fsm",
|
|
573
|
+
"state",
|
|
574
|
+
"duration",
|
|
575
|
+
"time"
|
|
576
|
+
],
|
|
577
|
+
menuPath: [
|
|
578
|
+
"State Machine",
|
|
579
|
+
"Get State Duration"
|
|
580
|
+
],
|
|
581
|
+
isPure: true,
|
|
582
|
+
inputs: [],
|
|
583
|
+
outputs: [
|
|
584
|
+
{
|
|
585
|
+
name: "duration",
|
|
586
|
+
displayName: "Duration (ms)",
|
|
587
|
+
type: "float"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
name: "seconds",
|
|
591
|
+
displayName: "Seconds",
|
|
592
|
+
type: "float"
|
|
593
|
+
}
|
|
594
|
+
],
|
|
595
|
+
color: "#8b5a8b"
|
|
596
|
+
};
|
|
597
|
+
var _GetStateDurationExecutor = class _GetStateDurationExecutor {
|
|
598
|
+
execute(_node, context) {
|
|
599
|
+
const ctx = context;
|
|
600
|
+
const duration = ctx.stateMachine?.currentStateDuration ?? 0;
|
|
601
|
+
return {
|
|
602
|
+
outputs: {
|
|
603
|
+
duration,
|
|
604
|
+
seconds: duration / 1e3
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
__name(_GetStateDurationExecutor, "GetStateDurationExecutor");
|
|
610
|
+
var GetStateDurationExecutor = _GetStateDurationExecutor;
|
|
611
|
+
var EvaluateTransitionsTemplate = {
|
|
612
|
+
type: "EvaluateTransitions",
|
|
613
|
+
title: "Evaluate Transitions",
|
|
614
|
+
category: "logic",
|
|
615
|
+
description: "Evaluate and execute automatic transitions / \u8BC4\u4F30\u5E76\u6267\u884C\u81EA\u52A8\u8F6C\u6362",
|
|
616
|
+
keywords: [
|
|
617
|
+
"fsm",
|
|
618
|
+
"state",
|
|
619
|
+
"transition",
|
|
620
|
+
"evaluate",
|
|
621
|
+
"auto"
|
|
622
|
+
],
|
|
623
|
+
menuPath: [
|
|
624
|
+
"State Machine",
|
|
625
|
+
"Evaluate Transitions"
|
|
626
|
+
],
|
|
627
|
+
isPure: false,
|
|
628
|
+
inputs: [
|
|
629
|
+
{
|
|
630
|
+
name: "exec",
|
|
631
|
+
displayName: "",
|
|
632
|
+
type: "exec"
|
|
633
|
+
}
|
|
634
|
+
],
|
|
635
|
+
outputs: [
|
|
636
|
+
{
|
|
637
|
+
name: "exec",
|
|
638
|
+
displayName: "",
|
|
639
|
+
type: "exec"
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
name: "transitioned",
|
|
643
|
+
displayName: "Transitioned",
|
|
644
|
+
type: "bool"
|
|
645
|
+
}
|
|
646
|
+
],
|
|
647
|
+
color: "#8b5a8b"
|
|
648
|
+
};
|
|
649
|
+
var _EvaluateTransitionsExecutor = class _EvaluateTransitionsExecutor {
|
|
650
|
+
execute(_node, context) {
|
|
651
|
+
const ctx = context;
|
|
652
|
+
const transitioned = ctx.stateMachine?.evaluateTransitions() ?? false;
|
|
653
|
+
return {
|
|
654
|
+
outputs: {
|
|
655
|
+
transitioned
|
|
656
|
+
},
|
|
657
|
+
nextExec: "exec"
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
__name(_EvaluateTransitionsExecutor, "EvaluateTransitionsExecutor");
|
|
662
|
+
var EvaluateTransitionsExecutor = _EvaluateTransitionsExecutor;
|
|
663
|
+
var ResetStateMachineTemplate = {
|
|
664
|
+
type: "ResetStateMachine",
|
|
665
|
+
title: "Reset State Machine",
|
|
666
|
+
category: "logic",
|
|
667
|
+
description: "Reset state machine to initial state / \u91CD\u7F6E\u72B6\u6001\u673A\u5230\u521D\u59CB\u72B6\u6001",
|
|
668
|
+
keywords: [
|
|
669
|
+
"fsm",
|
|
670
|
+
"state",
|
|
671
|
+
"reset",
|
|
672
|
+
"initial"
|
|
673
|
+
],
|
|
674
|
+
menuPath: [
|
|
675
|
+
"State Machine",
|
|
676
|
+
"Reset"
|
|
677
|
+
],
|
|
678
|
+
isPure: false,
|
|
679
|
+
inputs: [
|
|
680
|
+
{
|
|
681
|
+
name: "exec",
|
|
682
|
+
displayName: "",
|
|
683
|
+
type: "exec"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: "state",
|
|
687
|
+
displayName: "Initial State",
|
|
688
|
+
type: "string",
|
|
689
|
+
defaultValue: ""
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
outputs: [
|
|
693
|
+
{
|
|
694
|
+
name: "exec",
|
|
695
|
+
displayName: "",
|
|
696
|
+
type: "exec"
|
|
697
|
+
}
|
|
698
|
+
],
|
|
699
|
+
color: "#8b5a8b"
|
|
700
|
+
};
|
|
701
|
+
var _ResetStateMachineExecutor = class _ResetStateMachineExecutor {
|
|
702
|
+
execute(node, context) {
|
|
703
|
+
const ctx = context;
|
|
704
|
+
const state = ctx.evaluateInput(node.id, "state", "");
|
|
705
|
+
if (ctx.stateMachine) {
|
|
706
|
+
ctx.stateMachine.reset(state || void 0);
|
|
707
|
+
}
|
|
708
|
+
return {
|
|
709
|
+
outputs: {},
|
|
710
|
+
nextExec: "exec"
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
__name(_ResetStateMachineExecutor, "ResetStateMachineExecutor");
|
|
715
|
+
var ResetStateMachineExecutor = _ResetStateMachineExecutor;
|
|
716
|
+
var StateMachineNodeDefinitions = [
|
|
717
|
+
{
|
|
718
|
+
template: GetCurrentStateTemplate,
|
|
719
|
+
executor: new GetCurrentStateExecutor()
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
template: TransitionToTemplate,
|
|
723
|
+
executor: new TransitionToExecutor()
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
template: CanTransitionTemplate,
|
|
727
|
+
executor: new CanTransitionExecutor()
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
template: IsInStateTemplate,
|
|
731
|
+
executor: new IsInStateExecutor()
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
template: WasInStateTemplate,
|
|
735
|
+
executor: new WasInStateExecutor()
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
template: GetStateDurationTemplate,
|
|
739
|
+
executor: new GetStateDurationExecutor()
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
template: EvaluateTransitionsTemplate,
|
|
743
|
+
executor: new EvaluateTransitionsExecutor()
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
template: ResetStateMachineTemplate,
|
|
747
|
+
executor: new ResetStateMachineExecutor()
|
|
748
|
+
}
|
|
749
|
+
];
|
|
750
|
+
export {
|
|
751
|
+
CanTransitionExecutor,
|
|
752
|
+
CanTransitionTemplate,
|
|
753
|
+
EvaluateTransitionsExecutor,
|
|
754
|
+
EvaluateTransitionsTemplate,
|
|
755
|
+
GetCurrentStateExecutor,
|
|
756
|
+
GetCurrentStateTemplate,
|
|
757
|
+
GetStateDurationExecutor,
|
|
758
|
+
GetStateDurationTemplate,
|
|
759
|
+
IsInStateExecutor,
|
|
760
|
+
IsInStateTemplate,
|
|
761
|
+
ResetStateMachineExecutor,
|
|
762
|
+
ResetStateMachineTemplate,
|
|
763
|
+
StateMachine,
|
|
764
|
+
StateMachineNodeDefinitions,
|
|
765
|
+
StateMachineToken,
|
|
766
|
+
TransitionToExecutor,
|
|
767
|
+
TransitionToTemplate,
|
|
768
|
+
WasInStateExecutor,
|
|
769
|
+
WasInStateTemplate,
|
|
770
|
+
createStateMachine
|
|
771
|
+
};
|
|
772
|
+
//# sourceMappingURL=index.js.map
|