refactor: reorganize package structure and decouple framework packages (#338)
* refactor: reorganize package structure and decouple framework packages ## Package Structure Reorganization - Reorganized 55 packages into categorized subdirectories: - packages/framework/ - Generic framework (Laya/Cocos compatible) - packages/engine/ - ESEngine core modules - packages/rendering/ - Rendering modules (WASM dependent) - packages/physics/ - Physics modules - packages/streaming/ - World streaming - packages/network-ext/ - Network extensions - packages/editor/ - Editor framework and plugins - packages/rust/ - Rust WASM engine - packages/tools/ - Build tools and SDK ## Framework Package Decoupling - Decoupled behavior-tree and blueprint packages from ESEngine dependencies - Created abstracted interfaces (IBTAssetManager, IBehaviorTreeAssetContent) - ESEngine-specific code moved to esengine/ subpath exports - Framework packages now usable with Cocos/Laya without ESEngine ## CI Configuration - Updated CI to only type-check and lint framework packages - Added type-check:framework and lint:framework scripts ## Breaking Changes - Package import paths changed due to directory reorganization - ESEngine integrations now use subpath imports (e.g., '@esengine/behavior-tree/esengine') * fix: update es-engine file path after directory reorganization * docs: update README to focus on framework over engine * ci: only build framework packages, remove Rust/WASM dependencies * fix: remove esengine subpath from behavior-tree and blueprint builds ESEngine integration code will only be available in full engine builds. Framework packages are now purely engine-agnostic. * fix: move network-protocols to framework, build both in CI * fix: update workflow paths from packages/core to packages/framework/core * fix: exclude esengine folder from type-check in behavior-tree and blueprint * fix: update network tsconfig references to new paths * fix: add test:ci:framework to only test framework packages in CI * fix: only build core and math npm packages in CI * fix: exclude test files from CodeQL and fix string escaping security issue
This commit is contained in:
201
packages/engine/script-runtime/src/nodes/GameInfoNodes.ts
Normal file
201
packages/engine/script-runtime/src/nodes/GameInfoNodes.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* @zh 游戏信息节点
|
||||
* @en Game Info Nodes
|
||||
*
|
||||
* @zh 提供获取游戏状态信息的能力
|
||||
* @en Provides access to game state information
|
||||
*/
|
||||
|
||||
import type { BlueprintNodeTemplate, BlueprintNode } from '@esengine/blueprint';
|
||||
import type { INodeExecutor, ExecutionResult } from '@esengine/blueprint';
|
||||
import type { IGameState } from '../vm/ServerExecutionContext';
|
||||
|
||||
// =============================================================================
|
||||
// 扩展的执行上下文接口 | Extended Execution Context Interface
|
||||
// =============================================================================
|
||||
|
||||
interface ServerContext {
|
||||
gameState: IGameState | null;
|
||||
playerId: string;
|
||||
deltaTime: number;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GetTick Node | 获取 Tick 节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 获取 Tick 节点模板
|
||||
* @en Get Tick node template
|
||||
*/
|
||||
export const GetTickTemplate: BlueprintNodeTemplate = {
|
||||
type: 'GetTick',
|
||||
title: 'Get Tick',
|
||||
category: 'time',
|
||||
description: 'Get the current game tick / 获取当前游戏 tick',
|
||||
keywords: ['tick', 'time', 'frame', 'turn'],
|
||||
menuPath: ['Game', 'Get Tick'],
|
||||
isPure: true,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'tick',
|
||||
displayName: 'Tick',
|
||||
type: 'int'
|
||||
}
|
||||
],
|
||||
color: '#1e6b8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 获取 Tick 节点执行器
|
||||
* @en Get Tick node executor
|
||||
*/
|
||||
export class GetTickExecutor implements INodeExecutor {
|
||||
execute(_node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const tick = ctx.gameState?.tick ?? 0;
|
||||
|
||||
return {
|
||||
outputs: { tick }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GetPlayerId Node | 获取玩家 ID 节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 获取玩家 ID 节点模板
|
||||
* @en Get Player ID node template
|
||||
*/
|
||||
export const GetPlayerIdTemplate: BlueprintNodeTemplate = {
|
||||
type: 'GetPlayerId',
|
||||
title: 'Get Player ID',
|
||||
category: 'entity',
|
||||
description: 'Get the current player ID / 获取当前玩家 ID',
|
||||
keywords: ['player', 'id', 'owner', 'me'],
|
||||
menuPath: ['Game', 'Get Player ID'],
|
||||
isPure: true,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'playerId',
|
||||
displayName: 'Player ID',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
color: '#1e5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 获取玩家 ID 节点执行器
|
||||
* @en Get Player ID node executor
|
||||
*/
|
||||
export class GetPlayerIdExecutor implements INodeExecutor {
|
||||
execute(_node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
|
||||
return {
|
||||
outputs: { playerId: ctx.playerId }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GetDeltaTime Node | 获取增量时间节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 获取增量时间节点模板
|
||||
* @en Get Delta Time node template
|
||||
*/
|
||||
export const GetDeltaTimeTemplate: BlueprintNodeTemplate = {
|
||||
type: 'GetDeltaTime',
|
||||
title: 'Get Delta Time',
|
||||
category: 'time',
|
||||
description: 'Get the time since last tick (seconds) / 获取距上次 tick 的时间(秒)',
|
||||
keywords: ['delta', 'time', 'dt', 'interval'],
|
||||
menuPath: ['Game', 'Get Delta Time'],
|
||||
isPure: true,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'deltaTime',
|
||||
displayName: 'Delta Time',
|
||||
type: 'float'
|
||||
}
|
||||
],
|
||||
color: '#1e6b8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 获取增量时间节点执行器
|
||||
* @en Get Delta Time node executor
|
||||
*/
|
||||
export class GetDeltaTimeExecutor implements INodeExecutor {
|
||||
execute(_node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
|
||||
return {
|
||||
outputs: { deltaTime: ctx.deltaTime }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GetGameState Node | 获取游戏状态节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 获取游戏状态节点模板
|
||||
* @en Get Game State node template
|
||||
*/
|
||||
export const GetGameStateTemplate: BlueprintNodeTemplate = {
|
||||
type: 'GetGameState',
|
||||
title: 'Get Game State',
|
||||
category: 'entity',
|
||||
description: 'Get the current game state object / 获取当前游戏状态对象',
|
||||
keywords: ['game', 'state', 'world', 'data'],
|
||||
menuPath: ['Game', 'Get Game State'],
|
||||
isPure: true,
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
name: 'state',
|
||||
displayName: 'State',
|
||||
type: 'object'
|
||||
}
|
||||
],
|
||||
color: '#1e5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 获取游戏状态节点执行器
|
||||
* @en Get Game State node executor
|
||||
*/
|
||||
export class GetGameStateExecutor implements INodeExecutor {
|
||||
execute(_node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
|
||||
return {
|
||||
outputs: { state: ctx.gameState }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 节点定义集合 | Node Definition Collection
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 游戏信息节点定义
|
||||
* @en Game info node definitions
|
||||
*/
|
||||
export const GameInfoNodeDefinitions = [
|
||||
{ template: GetTickTemplate, executor: new GetTickExecutor() },
|
||||
{ template: GetPlayerIdTemplate, executor: new GetPlayerIdExecutor() },
|
||||
{ template: GetDeltaTimeTemplate, executor: new GetDeltaTimeExecutor() },
|
||||
{ template: GetGameStateTemplate, executor: new GetGameStateExecutor() }
|
||||
];
|
||||
200
packages/engine/script-runtime/src/nodes/LogNodes.ts
Normal file
200
packages/engine/script-runtime/src/nodes/LogNodes.ts
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @zh 日志节点
|
||||
* @en Log Nodes
|
||||
*
|
||||
* @zh 提供日志记录能力
|
||||
* @en Provides logging capabilities
|
||||
*/
|
||||
|
||||
import type { BlueprintNodeTemplate, BlueprintNode } from '@esengine/blueprint';
|
||||
import type { INodeExecutor, ExecutionResult } from '@esengine/blueprint';
|
||||
|
||||
// =============================================================================
|
||||
// 扩展的执行上下文接口 | Extended Execution Context Interface
|
||||
// =============================================================================
|
||||
|
||||
interface ServerContext {
|
||||
evaluateInput(nodeId: string, pinName: string, defaultValue?: unknown): unknown;
|
||||
log: (message: string) => void;
|
||||
warn: (message: string) => void;
|
||||
error: (message: string) => void;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Log Node | 日志节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 日志节点模板
|
||||
* @en Log node template
|
||||
*/
|
||||
export const LogTemplate: BlueprintNodeTemplate = {
|
||||
type: 'Log',
|
||||
title: 'Log',
|
||||
category: 'debug',
|
||||
description: 'Log a message / 记录日志消息',
|
||||
keywords: ['log', 'print', 'debug', 'console'],
|
||||
menuPath: ['Debug', 'Log'],
|
||||
inputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
displayName: 'Message',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
}
|
||||
],
|
||||
color: '#5a5a5a'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 日志节点执行器
|
||||
* @en Log node executor
|
||||
*/
|
||||
export class LogExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const message = ctx.evaluateInput(node.id, 'message', '') as string;
|
||||
|
||||
ctx.log(String(message));
|
||||
|
||||
return {
|
||||
nextExec: 'exec'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Warn Node | 警告节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 警告节点模板
|
||||
* @en Warn node template
|
||||
*/
|
||||
export const WarnTemplate: BlueprintNodeTemplate = {
|
||||
type: 'Warn',
|
||||
title: 'Warn',
|
||||
category: 'debug',
|
||||
description: 'Log a warning message / 记录警告消息',
|
||||
keywords: ['warn', 'warning', 'debug', 'console'],
|
||||
menuPath: ['Debug', 'Warn'],
|
||||
inputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
displayName: 'Message',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
}
|
||||
],
|
||||
color: '#8b8b1e'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 警告节点执行器
|
||||
* @en Warn node executor
|
||||
*/
|
||||
export class WarnExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const message = ctx.evaluateInput(node.id, 'message', '') as string;
|
||||
|
||||
ctx.warn(String(message));
|
||||
|
||||
return {
|
||||
nextExec: 'exec'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Error Node | 错误节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 错误节点模板
|
||||
* @en Error node template
|
||||
*/
|
||||
export const ErrorTemplate: BlueprintNodeTemplate = {
|
||||
type: 'Error',
|
||||
title: 'Error',
|
||||
category: 'debug',
|
||||
description: 'Log an error message / 记录错误消息',
|
||||
keywords: ['error', 'debug', 'console'],
|
||||
menuPath: ['Debug', 'Error'],
|
||||
inputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
displayName: 'Message',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
}
|
||||
],
|
||||
color: '#8b1e1e'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 错误节点执行器
|
||||
* @en Error node executor
|
||||
*/
|
||||
export class ErrorExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const message = ctx.evaluateInput(node.id, 'message', '') as string;
|
||||
|
||||
ctx.error(String(message));
|
||||
|
||||
return {
|
||||
nextExec: 'exec'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 节点定义集合 | Node Definition Collection
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 日志节点定义
|
||||
* @en Log node definitions
|
||||
*/
|
||||
export const LogNodeDefinitions = [
|
||||
{ template: LogTemplate, executor: new LogExecutor() },
|
||||
{ template: WarnTemplate, executor: new WarnExecutor() },
|
||||
{ template: ErrorTemplate, executor: new ErrorExecutor() }
|
||||
];
|
||||
269
packages/engine/script-runtime/src/nodes/MemoryNodes.ts
Normal file
269
packages/engine/script-runtime/src/nodes/MemoryNodes.ts
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* @zh Memory 操作节点
|
||||
* @en Memory Operation Nodes
|
||||
*
|
||||
* @zh 提供玩家持久化数据的读写能力
|
||||
* @en Provides read/write access to player persistent data
|
||||
*/
|
||||
|
||||
import type { BlueprintNodeTemplate, BlueprintNode } from '@esengine/blueprint';
|
||||
import type { INodeExecutor, ExecutionResult } from '@esengine/blueprint';
|
||||
|
||||
// =============================================================================
|
||||
// 扩展的执行上下文接口 | Extended Execution Context Interface
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 服务器端执行上下文接口(用于节点)
|
||||
* @en Server-side execution context interface (for nodes)
|
||||
*/
|
||||
interface ServerContext {
|
||||
memory: Record<string, unknown>;
|
||||
evaluateInput(nodeId: string, pinName: string, defaultValue?: unknown): unknown;
|
||||
setOutputs(nodeId: string, outputs: Record<string, unknown>): void;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GetMemory Node | 获取 Memory 节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 获取 Memory 节点模板
|
||||
* @en Get Memory node template
|
||||
*/
|
||||
export const GetMemoryTemplate: BlueprintNodeTemplate = {
|
||||
type: 'GetMemory',
|
||||
title: 'Get Memory',
|
||||
category: 'variable',
|
||||
description: 'Get a value from player Memory / 从玩家 Memory 获取值',
|
||||
keywords: ['memory', 'get', 'read', 'load', 'data'],
|
||||
menuPath: ['Memory', 'Get Memory'],
|
||||
isPure: true,
|
||||
inputs: [
|
||||
{
|
||||
name: 'key',
|
||||
displayName: 'Key',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
},
|
||||
{
|
||||
name: 'defaultValue',
|
||||
displayName: 'Default',
|
||||
type: 'any',
|
||||
defaultValue: null
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'value',
|
||||
displayName: 'Value',
|
||||
type: 'any'
|
||||
}
|
||||
],
|
||||
color: '#8b5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 获取 Memory 节点执行器
|
||||
* @en Get Memory node executor
|
||||
*/
|
||||
export class GetMemoryExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const key = ctx.evaluateInput(node.id, 'key', '') as string;
|
||||
const defaultValue = ctx.evaluateInput(node.id, 'defaultValue', null);
|
||||
|
||||
const value = ctx.memory[key] ?? defaultValue;
|
||||
|
||||
return {
|
||||
outputs: { value }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// SetMemory Node | 设置 Memory 节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 设置 Memory 节点模板
|
||||
* @en Set Memory node template
|
||||
*/
|
||||
export const SetMemoryTemplate: BlueprintNodeTemplate = {
|
||||
type: 'SetMemory',
|
||||
title: 'Set Memory',
|
||||
category: 'variable',
|
||||
description: 'Set a value in player Memory / 在玩家 Memory 中设置值',
|
||||
keywords: ['memory', 'set', 'write', 'save', 'data'],
|
||||
menuPath: ['Memory', 'Set Memory'],
|
||||
inputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
displayName: 'Key',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
displayName: 'Value',
|
||||
type: 'any',
|
||||
defaultValue: null
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
}
|
||||
],
|
||||
color: '#8b5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 设置 Memory 节点执行器
|
||||
* @en Set Memory node executor
|
||||
*/
|
||||
export class SetMemoryExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const key = ctx.evaluateInput(node.id, 'key', '') as string;
|
||||
const value = ctx.evaluateInput(node.id, 'value', null);
|
||||
|
||||
if (key) {
|
||||
ctx.memory[key] = value;
|
||||
}
|
||||
|
||||
return {
|
||||
nextExec: 'exec'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HasMemoryKey Node | 检查 Memory 键节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 检查 Memory 键节点模板
|
||||
* @en Has Memory Key node template
|
||||
*/
|
||||
export const HasMemoryKeyTemplate: BlueprintNodeTemplate = {
|
||||
type: 'HasMemoryKey',
|
||||
title: 'Has Memory Key',
|
||||
category: 'variable',
|
||||
description: 'Check if a key exists in Memory / 检查 Memory 中是否存在某个键',
|
||||
keywords: ['memory', 'has', 'exists', 'check', 'key'],
|
||||
menuPath: ['Memory', 'Has Key'],
|
||||
isPure: true,
|
||||
inputs: [
|
||||
{
|
||||
name: 'key',
|
||||
displayName: 'Key',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exists',
|
||||
displayName: 'Exists',
|
||||
type: 'bool'
|
||||
}
|
||||
],
|
||||
color: '#8b5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 检查 Memory 键节点执行器
|
||||
* @en Has Memory Key node executor
|
||||
*/
|
||||
export class HasMemoryKeyExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const key = ctx.evaluateInput(node.id, 'key', '') as string;
|
||||
|
||||
const exists = key in ctx.memory;
|
||||
|
||||
return {
|
||||
outputs: { exists }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// DeleteMemory Node | 删除 Memory 节点
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh 删除 Memory 节点模板
|
||||
* @en Delete Memory node template
|
||||
*/
|
||||
export const DeleteMemoryTemplate: BlueprintNodeTemplate = {
|
||||
type: 'DeleteMemory',
|
||||
title: 'Delete Memory',
|
||||
category: 'variable',
|
||||
description: 'Delete a key from Memory / 从 Memory 中删除键',
|
||||
keywords: ['memory', 'delete', 'remove', 'clear', 'key'],
|
||||
menuPath: ['Memory', 'Delete'],
|
||||
inputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
displayName: 'Key',
|
||||
type: 'string',
|
||||
defaultValue: ''
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
name: 'exec',
|
||||
displayName: '',
|
||||
type: 'exec'
|
||||
}
|
||||
],
|
||||
color: '#8b5a8b'
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 删除 Memory 节点执行器
|
||||
* @en Delete Memory node executor
|
||||
*/
|
||||
export class DeleteMemoryExecutor implements INodeExecutor {
|
||||
execute(node: BlueprintNode, context: unknown): ExecutionResult {
|
||||
const ctx = context as ServerContext;
|
||||
const key = ctx.evaluateInput(node.id, 'key', '') as string;
|
||||
|
||||
if (key) {
|
||||
delete ctx.memory[key];
|
||||
}
|
||||
|
||||
return {
|
||||
nextExec: 'exec'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 节点定义集合 | Node Definition Collection
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @zh Memory 节点定义
|
||||
* @en Memory node definitions
|
||||
*/
|
||||
export const MemoryNodeDefinitions = [
|
||||
{ template: GetMemoryTemplate, executor: new GetMemoryExecutor() },
|
||||
{ template: SetMemoryTemplate, executor: new SetMemoryExecutor() },
|
||||
{ template: HasMemoryKeyTemplate, executor: new HasMemoryKeyExecutor() },
|
||||
{ template: DeleteMemoryTemplate, executor: new DeleteMemoryExecutor() }
|
||||
];
|
||||
84
packages/engine/script-runtime/src/nodes/index.ts
Normal file
84
packages/engine/script-runtime/src/nodes/index.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @zh 蓝图节点模块
|
||||
* @en Blueprint Nodes Module
|
||||
*
|
||||
* @zh 提供服务器端蓝图执行所需的通用节点
|
||||
* @en Provides common nodes for server-side blueprint execution
|
||||
*/
|
||||
|
||||
import { NodeRegistry } from '@esengine/blueprint';
|
||||
|
||||
// Memory Nodes
|
||||
export {
|
||||
GetMemoryTemplate,
|
||||
GetMemoryExecutor,
|
||||
SetMemoryTemplate,
|
||||
SetMemoryExecutor,
|
||||
HasMemoryKeyTemplate,
|
||||
HasMemoryKeyExecutor,
|
||||
DeleteMemoryTemplate,
|
||||
DeleteMemoryExecutor,
|
||||
MemoryNodeDefinitions
|
||||
} from './MemoryNodes';
|
||||
|
||||
// Log Nodes
|
||||
export {
|
||||
LogTemplate,
|
||||
LogExecutor,
|
||||
WarnTemplate,
|
||||
WarnExecutor,
|
||||
ErrorTemplate,
|
||||
ErrorExecutor,
|
||||
LogNodeDefinitions
|
||||
} from './LogNodes';
|
||||
|
||||
// Game Info Nodes
|
||||
export {
|
||||
GetTickTemplate,
|
||||
GetTickExecutor,
|
||||
GetPlayerIdTemplate,
|
||||
GetPlayerIdExecutor,
|
||||
GetDeltaTimeTemplate,
|
||||
GetDeltaTimeExecutor,
|
||||
GetGameStateTemplate,
|
||||
GetGameStateExecutor,
|
||||
GameInfoNodeDefinitions
|
||||
} from './GameInfoNodes';
|
||||
|
||||
// =============================================================================
|
||||
// 节点注册 | Node Registration
|
||||
// =============================================================================
|
||||
|
||||
import { MemoryNodeDefinitions } from './MemoryNodes';
|
||||
import { LogNodeDefinitions } from './LogNodes';
|
||||
import { GameInfoNodeDefinitions } from './GameInfoNodes';
|
||||
|
||||
/**
|
||||
* @zh 所有节点定义
|
||||
* @en All node definitions
|
||||
*/
|
||||
export const AllNodeDefinitions = [
|
||||
...MemoryNodeDefinitions,
|
||||
...LogNodeDefinitions,
|
||||
...GameInfoNodeDefinitions
|
||||
];
|
||||
|
||||
/**
|
||||
* @zh 注册所有 script-runtime 节点到 NodeRegistry
|
||||
* @en Register all script-runtime nodes to NodeRegistry
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { registerScriptRuntimeNodes } from '@esengine/script-runtime';
|
||||
*
|
||||
* // 在应用启动时调用 | Call at application startup
|
||||
* registerScriptRuntimeNodes();
|
||||
* ```
|
||||
*/
|
||||
export function registerScriptRuntimeNodes(): void {
|
||||
const registry = NodeRegistry.instance;
|
||||
|
||||
for (const { template, executor } of AllNodeDefinitions) {
|
||||
registry.register(template, executor);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user