Files
esengine/packages/engine/platform-wechat/src/EngineBridge.ts
YHH 155411e743 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
2025-12-26 14:50:35 +08:00

236 lines
6.5 KiB
TypeScript

/**
* Rust 引擎桥接层
* 负责在微信小游戏环境中初始化和管理 Rust WASM 引擎
*/
import type { IPlatformCanvas } from '@esengine/platform-common';
import { WeChatAdapter } from './WeChatAdapter';
/**
* 引擎配置
*/
export interface EngineBridgeConfig {
wasmPath: string;
canvasWidth?: number;
canvasHeight?: number;
enableWebGL2?: boolean;
}
/**
* 引擎桥接层
* 将微信平台能力桥接到 Rust WASM 引擎
*/
export class EngineBridge {
private _adapter: WeChatAdapter;
private _canvas: IPlatformCanvas;
private _gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;
private _wasmInstance: any = null;
private _config: EngineBridgeConfig;
constructor(adapter: WeChatAdapter, config: EngineBridgeConfig) {
this._adapter = adapter;
this._config = config;
// 创建主 Canvas
const windowInfo = adapter.getSystemInfo();
const width = config.canvasWidth ?? windowInfo.windowWidth;
const height = config.canvasHeight ?? windowInfo.windowHeight;
this._canvas = adapter.canvas.createCanvas(width, height);
}
/**
* 初始化引擎
*/
async initialize(): Promise<void> {
// 获取 WebGL 上下文
this._gl = this._getWebGLContext();
if (!this._gl) {
throw new Error('无法获取 WebGL 上下文');
}
// 加载 WASM 模块
const imports = this._createWASMImports();
this._wasmInstance = await this._adapter.wasm.instantiate(
this._config.wasmPath,
imports
);
// 初始化引擎
if (this._wasmInstance.exports.init) {
this._wasmInstance.exports.init();
}
}
/**
* 获取 WebGL 上下文
*/
private _getWebGLContext(): WebGLRenderingContext | WebGL2RenderingContext | null {
const contextType = this._config.enableWebGL2 ? 'webgl2' : 'webgl';
const gl = this._canvas.getContext(contextType, {
alpha: false,
antialias: false,
depth: false,
stencil: false,
premultipliedAlpha: true,
preserveDrawingBuffer: false
});
return gl as WebGLRenderingContext | WebGL2RenderingContext | null;
}
/**
* 创建 WASM 导入对象
*/
private _createWASMImports(): Record<string, Record<string, any>> {
return {
env: {
// 内存
memory: this._adapter.wasm.createMemory(256, 16384),
// 平台桥接函数
platform_log: (ptr: number, len: number) => {
const message = this._readString(ptr, len);
console.log('[Engine]', message);
},
platform_error: (ptr: number, len: number) => {
const message = this._readString(ptr, len);
console.error('[Engine]', message);
},
platform_now: () => {
return performance.now();
},
// WebGL 桥接
gl_bindBuffer: (target: number, buffer: number) => {
this._gl?.bindBuffer(target, this._getGLObject(buffer));
},
gl_bufferData: (target: number, dataPtr: number, dataLen: number, usage: number) => {
const data = this._readBuffer(dataPtr, dataLen);
this._gl?.bufferData(target, data, usage);
},
gl_clear: (mask: number) => {
this._gl?.clear(mask);
},
gl_clearColor: (r: number, g: number, b: number, a: number) => {
this._gl?.clearColor(r, g, b, a);
},
gl_drawArrays: (mode: number, first: number, count: number) => {
this._gl?.drawArrays(mode, first, count);
},
gl_drawElements: (mode: number, count: number, type: number, offset: number) => {
this._gl?.drawElements(mode, count, type, offset);
},
gl_enable: (cap: number) => {
this._gl?.enable(cap);
},
gl_disable: (cap: number) => {
this._gl?.disable(cap);
},
gl_viewport: (x: number, y: number, width: number, height: number) => {
this._gl?.viewport(x, y, width, height);
}
}
};
}
/**
* 从 WASM 内存读取字符串
*/
private _readString(ptr: number, len: number): string {
const memory = this._wasmInstance?.exports.memory as WebAssembly.Memory;
if (!memory) return '';
const bytes = new Uint8Array(memory.buffer, ptr, len);
return new TextDecoder().decode(bytes);
}
/**
* 从 WASM 内存读取缓冲区
*/
private _readBuffer(ptr: number, len: number): ArrayBuffer {
const memory = this._wasmInstance?.exports.memory as WebAssembly.Memory;
if (!memory) return new ArrayBuffer(0);
return memory.buffer.slice(ptr, ptr + len);
}
/**
* 获取 WebGL 对象(暂时简化实现)
*/
private _getGLObject(_id: number): WebGLBuffer | null {
// TODO: 实现 WebGL 对象管理
return null;
}
/**
* 获取 Canvas
*/
get canvas(): IPlatformCanvas {
return this._canvas;
}
/**
* 获取 WebGL 上下文
*/
get gl(): WebGLRenderingContext | WebGL2RenderingContext | null {
return this._gl;
}
/**
* 获取 WASM 实例
*/
get wasmInstance(): any {
return this._wasmInstance;
}
/**
* 清屏
*/
clear(r: number, g: number, b: number, a: number): void {
if (this._gl) {
this._gl.clearColor(r, g, b, a);
this._gl.clear(this._gl.COLOR_BUFFER_BIT);
}
}
/**
* 渲染一帧
*/
render(): void {
if (this._wasmInstance?.exports.render) {
this._wasmInstance.exports.render();
}
}
/**
* 更新逻辑
*/
update(deltaTime: number): void {
if (this._wasmInstance?.exports.update) {
this._wasmInstance.exports.update(deltaTime);
}
}
/**
* 销毁引擎
*/
dispose(): void {
if (this._wasmInstance?.exports.dispose) {
this._wasmInstance.exports.dispose();
}
this._wasmInstance = null;
this._gl = null;
}
}