feat: 集成Rust WASM渲染引擎与TypeScript ECS框架 (#228)
* feat: 集成Rust WASM渲染引擎与TypeScript ECS框架 * feat: 增强编辑器UI功能与跨平台支持 * fix: 修复CI测试和类型检查问题 * fix: 修复CI问题并提高测试覆盖率 * fix: 修复CI问题并提高测试覆盖率
This commit is contained in:
171
packages/ecs-engine-bindgen/src/systems/EngineRenderSystem.ts
Normal file
171
packages/ecs-engine-bindgen/src/systems/EngineRenderSystem.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Engine render system for ECS.
|
||||
* 用于ECS的引擎渲染系统。
|
||||
*/
|
||||
|
||||
import { EntitySystem, Matcher, Entity, ComponentType, ECSSystem, Component } from '@esengine/ecs-framework';
|
||||
import type { EngineBridge } from '../core/EngineBridge';
|
||||
import { RenderBatcher } from '../core/RenderBatcher';
|
||||
import { SpriteComponent } from '../components/SpriteComponent';
|
||||
import type { SpriteRenderData } from '../types';
|
||||
import type { ITransformComponent } from '../core/SpriteRenderHelper';
|
||||
|
||||
/**
|
||||
* Type for transform component constructor.
|
||||
* 变换组件构造函数类型。
|
||||
*/
|
||||
export type TransformComponentType = ComponentType & (new (...args: any[]) => Component & ITransformComponent);
|
||||
|
||||
/**
|
||||
* ECS System for rendering sprites using the Rust engine.
|
||||
* 使用Rust引擎渲染精灵的ECS系统。
|
||||
*
|
||||
* This system extends EntitySystem and integrates with the ECS lifecycle.
|
||||
* 此系统扩展EntitySystem并与ECS生命周期集成。
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Create transform component | 创建变换组件
|
||||
* @ECSComponent('Transform')
|
||||
* class Transform extends Component implements ITransformComponent {
|
||||
* position = { x: 0, y: 0 };
|
||||
* rotation = 0;
|
||||
* scale = { x: 1, y: 1 };
|
||||
* }
|
||||
*
|
||||
* // Initialize bridge | 初始化桥接
|
||||
* const bridge = new EngineBridge({ canvasId: 'canvas' });
|
||||
* await bridge.initialize();
|
||||
*
|
||||
* // Add system to scene | 将系统添加到场景
|
||||
* const renderSystem = new EngineRenderSystem(bridge, Transform);
|
||||
* scene.addSystem(renderSystem);
|
||||
* ```
|
||||
*/
|
||||
@ECSSystem('EngineRender', { updateOrder: 1000 }) // Render system executes last | 渲染系统最后执行
|
||||
export class EngineRenderSystem extends EntitySystem {
|
||||
private bridge: EngineBridge;
|
||||
private batcher: RenderBatcher;
|
||||
private transformType: TransformComponentType;
|
||||
|
||||
/**
|
||||
* Create a new engine render system.
|
||||
* 创建新的引擎渲染系统。
|
||||
*
|
||||
* @param bridge - Engine bridge instance | 引擎桥接实例
|
||||
* @param transformType - Transform component class (must implement ITransformComponent) | 变换组件类(必须实现ITransformComponent)
|
||||
*/
|
||||
constructor(bridge: EngineBridge, transformType: TransformComponentType) {
|
||||
// Match entities with both Sprite and Transform components
|
||||
// 匹配同时具有Sprite和Transform组件的实体
|
||||
super(Matcher.empty().all(SpriteComponent, transformType));
|
||||
|
||||
this.bridge = bridge;
|
||||
this.batcher = new RenderBatcher();
|
||||
this.transformType = transformType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when system is initialized.
|
||||
* 系统初始化时调用。
|
||||
*/
|
||||
public override initialize(): void {
|
||||
super.initialize();
|
||||
this.logger.info('EngineRenderSystem initialized | 引擎渲染系统初始化完成');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before processing entities.
|
||||
* 处理实体之前调用。
|
||||
*/
|
||||
protected begin(): void {
|
||||
// Clear the batch | 清空批处理
|
||||
this.batcher.clear();
|
||||
|
||||
// Clear screen | 清屏
|
||||
this.bridge.clear(0, 0, 0, 1);
|
||||
|
||||
// Update input | 更新输入
|
||||
this.bridge.updateInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all matched entities.
|
||||
* 处理所有匹配的实体。
|
||||
*
|
||||
* @param entities - Entities to process | 要处理的实体
|
||||
*/
|
||||
protected process(entities: readonly Entity[]): void {
|
||||
for (const entity of entities) {
|
||||
const sprite = entity.getComponent(SpriteComponent);
|
||||
const transform = entity.getComponent(this.transformType) as unknown as ITransformComponent | null;
|
||||
|
||||
if (!sprite || !transform || !sprite.visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate UV with flip | 计算带翻转的UV
|
||||
let uv = sprite.uv;
|
||||
if (sprite.flipX || sprite.flipY) {
|
||||
uv = [...sprite.uv] as [number, number, number, number];
|
||||
if (sprite.flipX) {
|
||||
[uv[0], uv[2]] = [uv[2], uv[0]];
|
||||
}
|
||||
if (sprite.flipY) {
|
||||
[uv[1], uv[3]] = [uv[3], uv[1]];
|
||||
}
|
||||
}
|
||||
|
||||
const renderData: SpriteRenderData = {
|
||||
x: transform.position.x,
|
||||
y: transform.position.y,
|
||||
rotation: transform.rotation,
|
||||
scaleX: transform.scale.x,
|
||||
scaleY: transform.scale.y,
|
||||
originX: sprite.originX,
|
||||
originY: sprite.originY,
|
||||
textureId: sprite.textureId,
|
||||
uv,
|
||||
color: sprite.color
|
||||
};
|
||||
|
||||
this.batcher.addSprite(renderData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after processing entities.
|
||||
* 处理实体之后调用。
|
||||
*/
|
||||
protected end(): void {
|
||||
// Submit batch and render | 提交批处理并渲染
|
||||
if (!this.batcher.isEmpty) {
|
||||
this.bridge.submitSprites(this.batcher.getSprites());
|
||||
}
|
||||
this.bridge.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of sprites rendered.
|
||||
* 获取渲染的精灵数量。
|
||||
*/
|
||||
get spriteCount(): number {
|
||||
return this.batcher.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get engine statistics.
|
||||
* 获取引擎统计信息。
|
||||
*/
|
||||
getStats() {
|
||||
return this.bridge.getStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a texture.
|
||||
* 加载纹理。
|
||||
*/
|
||||
loadTexture(id: number, url: string): void {
|
||||
this.bridge.loadTexture(id, url);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user