* 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
208 lines
6.2 KiB
TypeScript
208 lines
6.2 KiB
TypeScript
/**
|
||
* 物理运行时模块
|
||
*
|
||
* 提供 Rapier2D 物理引擎的 ECS 集成
|
||
*/
|
||
|
||
import type { IScene, ServiceContainer, IComponentRegistry } from '@esengine/ecs-framework';
|
||
import type { IRuntimeModule, IRuntimePlugin, ModuleManifest, SystemContext } from '@esengine/engine-core';
|
||
import { WasmLibraryLoaderFactory } from '@esengine/platform-common';
|
||
import type * as RAPIER from '@esengine/rapier2d';
|
||
|
||
import { Rigidbody2DComponent } from './components/Rigidbody2DComponent';
|
||
import { BoxCollider2DComponent } from './components/BoxCollider2DComponent';
|
||
import { CircleCollider2DComponent } from './components/CircleCollider2DComponent';
|
||
import { CapsuleCollider2DComponent } from './components/CapsuleCollider2DComponent';
|
||
import { PolygonCollider2DComponent } from './components/PolygonCollider2DComponent';
|
||
import { Physics2DSystem } from './systems/Physics2DSystem';
|
||
import { Physics2DService } from './services/Physics2DService';
|
||
import {
|
||
Physics2DQueryToken,
|
||
Physics2DSystemToken,
|
||
Physics2DWorldToken,
|
||
PhysicsConfigToken,
|
||
CollisionLayerConfigToken,
|
||
type IPhysics2DQuery,
|
||
type PhysicsConfig
|
||
} from './tokens';
|
||
import { CollisionLayerConfig } from './services/CollisionLayerConfig';
|
||
|
||
// 注册 Rapier2D 加载器
|
||
import './loaders';
|
||
|
||
// 重新导出 tokens 和类型 | Re-export tokens and types
|
||
export {
|
||
Physics2DQueryToken,
|
||
Physics2DSystemToken,
|
||
Physics2DWorldToken,
|
||
PhysicsConfigToken,
|
||
CollisionLayerConfigToken,
|
||
type IPhysics2DQuery,
|
||
type PhysicsConfig
|
||
} from './tokens';
|
||
|
||
/**
|
||
* 物理运行时模块
|
||
*
|
||
* 负责:
|
||
* 1. 加载并初始化 Rapier2D WASM 模块(跨平台)
|
||
* 2. 注册物理组件
|
||
* 3. 注册物理服务
|
||
* 4. 创建物理系统
|
||
*
|
||
* @example
|
||
* ```typescript
|
||
* // 作为插件使用
|
||
* runtimePluginManager.register(PhysicsPlugin);
|
||
* runtimePluginManager.enable('@esengine/physics-rapier2d');
|
||
*
|
||
* // 插件会自动:
|
||
* // 1. 检测平台并选择合适的加载器
|
||
* // 2. 安装必要的 polyfills(如微信小游戏的 TextDecoder)
|
||
* // 3. 加载 Rapier2D WASM 模块
|
||
* // 4. 注册物理组件和系统
|
||
* ```
|
||
*/
|
||
class PhysicsRuntimeModule implements IRuntimeModule {
|
||
private _rapierModule: typeof RAPIER | null = null;
|
||
private _physicsSystem: Physics2DSystem | null = null;
|
||
|
||
/**
|
||
* 初始化物理模块
|
||
*
|
||
* 使用平台适配的加载器加载 Rapier2D
|
||
*/
|
||
async onInitialize(): Promise<void> {
|
||
// 使用工厂创建平台对应的加载器
|
||
const loader = WasmLibraryLoaderFactory.createLoader<typeof RAPIER>('rapier2d');
|
||
|
||
// 获取平台信息
|
||
const platformInfo = loader.getPlatformInfo();
|
||
console.log(`[Physics] 平台: ${platformInfo.type}`);
|
||
console.log(`[Physics] WASM 支持: ${platformInfo.supportsWasm}`);
|
||
|
||
if (platformInfo.needsPolyfills.length > 0) {
|
||
console.log(`[Physics] 需要 Polyfills: ${platformInfo.needsPolyfills.join(', ')}`);
|
||
}
|
||
|
||
// 检查平台支持
|
||
if (!loader.isSupported()) {
|
||
throw new Error(
|
||
`[Physics] 当前平台不支持 Rapier2D: ${platformInfo.type}。` +
|
||
'请检查 WebAssembly 支持情况。'
|
||
);
|
||
}
|
||
|
||
// 加载 Rapier2D
|
||
this._rapierModule = await loader.load();
|
||
console.log('[Physics] Rapier2D 加载完成');
|
||
}
|
||
|
||
/**
|
||
* 注册物理组件
|
||
* Register physics components
|
||
*
|
||
* @param registry - 组件注册表 | Component registry
|
||
*/
|
||
registerComponents(registry: IComponentRegistry): void {
|
||
registry.register(Rigidbody2DComponent);
|
||
registry.register(BoxCollider2DComponent);
|
||
registry.register(CircleCollider2DComponent);
|
||
registry.register(CapsuleCollider2DComponent);
|
||
registry.register(PolygonCollider2DComponent);
|
||
}
|
||
|
||
/**
|
||
* 注册物理服务
|
||
*
|
||
* @param services - 服务容器
|
||
*/
|
||
registerServices(services: ServiceContainer): void {
|
||
services.registerSingleton(Physics2DService);
|
||
}
|
||
|
||
/**
|
||
* 创建物理系统
|
||
*
|
||
* @param scene - 目标场景
|
||
* @param context - 系统上下文
|
||
*/
|
||
createSystems(scene: IScene, context: SystemContext): void {
|
||
// 从服务注册表获取配置 | Get config from service registry
|
||
const physicsConfig = context.services.get(PhysicsConfigToken);
|
||
|
||
const physicsSystem = new Physics2DSystem({
|
||
physics: physicsConfig,
|
||
updateOrder: -1000
|
||
});
|
||
|
||
scene.addSystem(physicsSystem);
|
||
this._physicsSystem = physicsSystem;
|
||
|
||
if (this._rapierModule) {
|
||
physicsSystem.initializeWithRapier(this._rapierModule);
|
||
}
|
||
|
||
// 注册服务 | Register services
|
||
context.services.register(Physics2DSystemToken, physicsSystem);
|
||
context.services.register(Physics2DWorldToken, physicsSystem.world);
|
||
context.services.register(Physics2DQueryToken, physicsSystem);
|
||
context.services.register(CollisionLayerConfigToken, CollisionLayerConfig.getInstance());
|
||
}
|
||
|
||
/**
|
||
* 销毁物理模块
|
||
*/
|
||
onDestroy(): void {
|
||
this._physicsSystem = null;
|
||
this._rapierModule = null;
|
||
}
|
||
|
||
/**
|
||
* 获取 Rapier 模块
|
||
*
|
||
* @returns Rapier 模块,如果未加载则返回 null
|
||
*/
|
||
getRapierModule(): typeof RAPIER | null {
|
||
return this._rapierModule;
|
||
}
|
||
|
||
/**
|
||
* 获取物理系统
|
||
*
|
||
* @returns 物理系统,如果未创建则返回 null
|
||
*/
|
||
getPhysicsSystem(): Physics2DSystem | null {
|
||
return this._physicsSystem;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 模块清单
|
||
*/
|
||
const manifest: ModuleManifest = {
|
||
id: 'physics-rapier2d',
|
||
name: '@esengine/physics-rapier2d',
|
||
displayName: 'Physics 2D (Rapier)',
|
||
version: '1.0.0',
|
||
description: '基于 Rapier2D 的确定性 2D 物理引擎(支持跨平台)',
|
||
category: 'Physics',
|
||
icon: 'Atom',
|
||
isCore: false,
|
||
defaultEnabled: false,
|
||
isEngineModule: true,
|
||
dependencies: ['core', 'math'],
|
||
exports: { components: ['RigidBody2D'] },
|
||
requiresWasm: true
|
||
};
|
||
|
||
/**
|
||
* 物理插件
|
||
*/
|
||
export const PhysicsPlugin: IRuntimePlugin = {
|
||
manifest,
|
||
runtimeModule: new PhysicsRuntimeModule()
|
||
};
|
||
|
||
export { PhysicsRuntimeModule };
|