Files
esengine/packages/engine/src/lib.rs

726 lines
25 KiB
Rust
Raw Normal View History

//! ES Engine - High-performance 2D game engine for web and mobile platforms.
//! ES引擎 - 高性能2D游戏引擎支持Web和移动平台。
//!
//! # Architecture | 架构
//!
//! The engine is designed with a modular architecture:
//! 引擎采用模块化架构设计:
//!
//! - `core` - Engine lifecycle and context management | 引擎生命周期和上下文管理
//! - `renderer` - 2D rendering with batch optimization | 2D渲染与批处理优化
//! - `math` - Mathematical primitives (vectors, matrices) | 数学基元(向量、矩阵)
//! - `resource` - Asset loading and management | 资源加载和管理
//! - `input` - Keyboard, mouse, and touch input | 键盘、鼠标和触摸输入
//! - `platform` - Platform abstraction layer | 平台抽象层
//!
//! # Example | 示例
//!
//! ```typescript
//! import { GameEngine } from 'es-engine';
//!
//! const engine = new GameEngine('canvas');
//! engine.loadTexture('player', 'assets/player.png');
//!
//! function gameLoop() {
//! engine.clear(0.0, 0.0, 0.0, 1.0);
//! engine.submitSpriteBatch(transforms, textureIds, uvs, colors);
//! engine.render();
//! requestAnimationFrame(gameLoop);
//! }
//! ```
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
use wasm_bindgen::prelude::*;
// Module declarations | 模块声明
pub mod core;
pub mod math;
pub mod platform;
pub mod renderer;
pub mod resource;
pub mod input;
// Re-exports | 重新导出
pub use crate::core::{Engine, EngineConfig};
pub use crate::core::error::{EngineError, Result};
/// Initialize panic hook for better error messages in console.
/// 初始化panic hook以在控制台显示更好的错误信息。
#[wasm_bindgen(start)]
pub fn init() {
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
// Initialize logger | 初始化日志
console_log::init_with_level(log::Level::Debug)
.expect("Failed to initialize logger | 日志初始化失败");
log::info!("ES Engine initialized | ES引擎初始化完成");
}
/// Game engine main interface exposed to JavaScript.
/// 暴露给JavaScript的游戏引擎主接口。
///
/// This is the primary entry point for the engine from TypeScript/JavaScript.
/// 这是从TypeScript/JavaScript访问引擎的主要入口点。
#[wasm_bindgen]
pub struct GameEngine {
engine: Engine,
}
#[wasm_bindgen]
impl GameEngine {
/// Create a new game engine instance.
/// 创建新的游戏引擎实例。
///
/// # Arguments | 参数
/// * `canvas_id` - The HTML canvas element ID | HTML canvas元素ID
///
/// # Returns | 返回
/// A new GameEngine instance or an error | 新的GameEngine实例或错误
#[wasm_bindgen(constructor)]
pub fn new(canvas_id: &str) -> std::result::Result<GameEngine, JsValue> {
let config = EngineConfig::default();
let engine = Engine::new(canvas_id, config)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(GameEngine { engine })
}
/// Create a new game engine from external WebGL context.
/// 从外部 WebGL 上下文创建引擎。
///
/// This is designed for WeChat MiniGame and similar environments.
/// 适用于微信小游戏等环境。
#[wasm_bindgen(js_name = fromExternal)]
pub fn from_external(
gl_context: JsValue,
width: u32,
height: u32,
) -> std::result::Result<GameEngine, JsValue> {
let config = EngineConfig::default();
let engine = Engine::from_external(gl_context, width, height, config)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(GameEngine { engine })
}
/// Clear the screen with specified color.
/// 使用指定颜色清除屏幕。
///
/// # Arguments | 参数
/// * `r` - Red component (0.0-1.0) | 红色分量
/// * `g` - Green component (0.0-1.0) | 绿色分量
/// * `b` - Blue component (0.0-1.0) | 蓝色分量
/// * `a` - Alpha component (0.0-1.0) | 透明度分量
pub fn clear(&self, r: f32, g: f32, b: f32, a: f32) {
self.engine.clear(r, g, b, a);
}
/// Get canvas width.
/// 获取画布宽度。
#[wasm_bindgen(getter)]
pub fn width(&self) -> u32 {
self.engine.width()
}
/// Get canvas height.
/// 获取画布高度。
#[wasm_bindgen(getter)]
pub fn height(&self) -> u32 {
self.engine.height()
}
/// Submit sprite batch data for rendering.
/// 提交精灵批次数据进行渲染。
///
/// # Arguments | 参数
/// * `transforms` - Float32Array [x, y, rotation, scaleX, scaleY, originX, originY] per sprite
/// 每个精灵的变换数据
/// * `texture_ids` - Uint32Array of texture IDs | 纹理ID数组
/// * `uvs` - Float32Array [u0, v0, u1, v1] per sprite | 每个精灵的UV坐标
/// * `colors` - Uint32Array of packed RGBA colors | 打包的RGBA颜色数组
feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
/// * `material_ids` - Uint32Array of material IDs (0 = default) | 材质ID数组0 = 默认)
#[wasm_bindgen(js_name = submitSpriteBatch)]
pub fn submit_sprite_batch(
&mut self,
transforms: &[f32],
texture_ids: &[u32],
uvs: &[f32],
colors: &[u32],
feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
material_ids: &[u32],
) -> std::result::Result<(), JsValue> {
self.engine
feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
.submit_sprite_batch(transforms, texture_ids, uvs, colors, material_ids)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Render the current frame.
/// 渲染当前帧。
pub fn render(&mut self) -> std::result::Result<(), JsValue> {
self.engine
.render()
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Render sprites as overlay (without clearing screen).
/// 渲染精灵作为叠加层(不清除屏幕)。
///
/// This is used for UI rendering on top of the world content.
/// 用于在世界内容上渲染 UI。
#[wasm_bindgen(js_name = renderOverlay)]
pub fn render_overlay(&mut self) -> std::result::Result<(), JsValue> {
self.engine
.render_overlay()
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Load a texture from URL.
/// 从URL加载纹理。
///
/// # Arguments | 参数
/// * `id` - Unique texture identifier | 唯一纹理标识符
/// * `url` - Image URL to load | 要加载的图片URL
#[wasm_bindgen(js_name = loadTexture)]
pub fn load_texture(&mut self, id: u32, url: &str) -> std::result::Result<(), JsValue> {
self.engine
.load_texture(id, url)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Load texture by path, returning texture ID.
/// 按路径加载纹理返回纹理ID。
///
/// # Arguments | 参数
/// * `path` - Image path/URL to load | 要加载的图片路径/URL
#[wasm_bindgen(js_name = loadTextureByPath)]
pub fn load_texture_by_path(&mut self, path: &str) -> std::result::Result<u32, JsValue> {
self.engine
.load_texture_by_path(path)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Get texture ID by path.
/// 按路径获取纹理ID。
///
/// # Arguments | 参数
/// * `path` - Image path to lookup | 要查找的图片路径
#[wasm_bindgen(js_name = getTextureIdByPath)]
pub fn get_texture_id_by_path(&self, path: &str) -> Option<u32> {
self.engine.get_texture_id_by_path(path)
}
/// Get or load texture by path.
/// 按路径获取或加载纹理。
///
/// # Arguments | 参数
/// * `path` - Image path/URL | 图片路径/URL
#[wasm_bindgen(js_name = getOrLoadTextureByPath)]
pub fn get_or_load_by_path(&mut self, path: &str) -> std::result::Result<u32, JsValue> {
self.engine
.get_or_load_by_path(path)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
feat: 纹理路径稳定 ID 与架构改进 (#305) * feat(asset-system): 实现路径稳定 ID 生成器 使用 FNV-1a hash 算法为纹理生成稳定的运行时 ID: - 新增 _pathIdCache 静态缓存,跨 Play/Stop 循环保持稳定 - 新增 getStableIdForPath() 方法,相同路径永远返回相同 ID - 修改 loadTextureForComponent/loadTextureByGuid 使用稳定 ID - clearTextureMappings() 不再清除 _pathIdCache 这解决了 Play/Stop 后纹理 ID 失效的根本问题。 * fix(runtime-core): 移除 Play/Stop 循环中的 clearTextureMappings 调用 使用路径稳定 ID 后,不再需要在快照保存/恢复时清除纹理缓存: - saveSceneSnapshot() 移除 clearTextureMappings() 调用 - restoreSceneSnapshot() 移除 clearTextureMappings() 调用 - 组件保存的 textureId 在 Play/Stop 后仍然有效 * fix(editor-core): 修复场景切换时的资源泄漏 在 openScene() 加载新场景前先卸载旧场景资源: - 调用 sceneResourceManager.unloadSceneResources() 释放旧资源 - 使用引用计数机制,仅卸载不再被引用的资源 - 路径稳定 ID 缓存不受影响,保持 ID 稳定性 * fix(runtime-core): 修复 PluginManager 组件注册类型错误 将 ComponentRegistry 类改为 GlobalComponentRegistry 实例: - registerComponents() 期望 IComponentRegistry 接口实例 - GlobalComponentRegistry 是 ComponentRegistry 的全局实例 * refactor(core): 提取 IComponentRegistry 接口 将组件注册表抽象为接口,支持场景级组件注册: - 新增 IComponentRegistry 接口定义 - Scene 持有独立的 componentRegistry 实例 - 支持从 GlobalComponentRegistry 克隆 - 各系统支持传入自定义注册表 * refactor(engine-core): 改进插件服务注册机制 - 更新 IComponentRegistry 类型引用 - 优化 PluginServiceRegistry 服务管理 * refactor(modules): 适配新的组件注册接口 更新各模块 RuntimeModule 使用 IComponentRegistry 接口: - audio, behavior-tree, camera - sprite, tilemap, world-streaming * fix(physics-rapier2d): 修复物理插件组件注册 - PhysicsEditorPlugin 添加 runtimeModule 引用 - 适配 IComponentRegistry 接口 - 修复物理组件在场景加载时未注册的问题 * feat(editor-core): 添加 UserCodeService 就绪信号机制 - 新增 waitForReady()/signalReady() API - 支持等待用户脚本编译完成 - 解决场景加载时组件未注册的时序问题 * fix(editor-app): 在编译完成后调用 signalReady() 确保用户脚本编译完成后发出就绪信号: - 编译成功后调用 userCodeService.signalReady() - 编译失败也要发出信号,避免阻塞场景加载 * feat(editor-core): 改进编辑器核心服务 - EntityStoreService 添加调试日志 - AssetRegistryService 优化资产注册 - PluginManager 改进插件管理 - IFileAPI 添加 getFileMtime 接口 * feat(engine): 改进 Rust 纹理管理器 - 支持任意 ID 的纹理加载(非递增) - 添加纹理状态追踪 API - 优化纹理缓存清理机制 - 更新 TypeScript 绑定 * feat(ui): 添加场景切换和文本闪烁组件 新增组件: - SceneLoadTriggerComponent: 场景切换触发器 - TextBlinkComponent: 文本闪烁效果 新增系统: - SceneLoadTriggerSystem: 处理场景切换逻辑 - TextBlinkSystem: 处理文本闪烁动画 其他改进: - UIRuntimeModule 适配新组件注册接口 - UI 渲染系统优化 * feat(editor-app): 添加外部文件修改检测 - 新增 ExternalModificationDialog 组件 - TauriFileAPI 支持 getFileMtime - 场景文件被外部修改时提示用户 * feat(editor-app): 添加渲染调试面板 - 新增 RenderDebugService 和调试面板 UI - App/ContentBrowser 添加调试日志 - TitleBar/Viewport 优化 - DialogManager 改进 * refactor(editor-app): 编辑器服务和组件优化 - EngineService 改进引擎集成 - EditorEngineSync 同步优化 - AssetFileInspector 改进 - VectorFieldEditors 优化 - InstantiatePrefabCommand 改进 * feat(i18n): 更新国际化翻译 - 添加新功能相关翻译 - 更新中文、英文、西班牙文 * feat(tauri): 添加文件修改时间查询命令 - 新增 get_file_mtime 命令 - 支持检测文件外部修改 * refactor(particle): 粒子系统改进 - 适配新的组件注册接口 - ParticleSystem 优化 - 添加单元测试 * refactor(platform): 平台适配层优化 - BrowserRuntime 改进 - 新增 RuntimeSceneManager 服务 - 导出优化 * refactor(asset-system-editor): 资产元数据改进 - AssetMetaFile 优化 - 导出调整 * fix(asset-system): 移除未使用的 TextureLoader 导入 * fix(tests): 更新测试以使用 GlobalComponentRegistry 实例 修复多个测试文件以适配 ComponentRegistry 从静态类变为实例类的变更: - ComponentStorage.test.ts: 使用 GlobalComponentRegistry.reset() - EntitySerializer.test.ts: 使用 GlobalComponentRegistry 实例 - IncrementalSerialization.test.ts: 使用 GlobalComponentRegistry 实例 - SceneSerializer.test.ts: 使用 GlobalComponentRegistry 实例 - ComponentRegistry.extended.test.ts: 使用 GlobalComponentRegistry,同时注册到 scene.componentRegistry - SystemTypes.test.ts: 在 Scene 创建前注册组件 - QuerySystem.test.ts: mockScene 添加 componentRegistry
2025-12-16 12:46:14 +08:00
/// 获取纹理加载状态
/// Get texture loading state
///
/// # Arguments | 参数
/// * `id` - Texture ID | 纹理ID
///
/// # Returns | 返回
/// State string: "loading", "ready", or "failed:reason"
/// 状态字符串:"loading"、"ready" 或 "failed:原因"
#[wasm_bindgen(js_name = getTextureState)]
pub fn get_texture_state(&self, id: u32) -> String {
use crate::renderer::texture::TextureState;
match self.engine.get_texture_state(id) {
TextureState::Loading => "loading".to_string(),
TextureState::Ready => "ready".to_string(),
TextureState::Failed(reason) => format!("failed:{}", reason),
}
}
/// 检查纹理是否已就绪
/// Check if texture is ready to use
///
/// # Arguments | 参数
/// * `id` - Texture ID | 纹理ID
#[wasm_bindgen(js_name = isTextureReady)]
pub fn is_texture_ready(&self, id: u32) -> bool {
self.engine.is_texture_ready(id)
}
/// 获取正在加载中的纹理数量
/// Get the number of textures currently loading
#[wasm_bindgen(js_name = getTextureLoadingCount)]
pub fn get_texture_loading_count(&self) -> u32 {
self.engine.get_texture_loading_count()
}
/// Check if a key is currently pressed.
/// 检查某个键是否当前被按下。
///
/// # Arguments | 参数
/// * `key_code` - The key code to check | 要检查的键码
#[wasm_bindgen(js_name = isKeyDown)]
pub fn is_key_down(&self, key_code: &str) -> bool {
self.engine.is_key_down(key_code)
}
/// Update input state. Should be called once per frame.
/// 更新输入状态。应该每帧调用一次。
#[wasm_bindgen(js_name = updateInput)]
pub fn update_input(&mut self) {
self.engine.update_input();
}
/// Resize viewport.
/// 调整视口大小。
///
/// # Arguments | 参数
/// * `width` - New viewport width | 新视口宽度
/// * `height` - New viewport height | 新视口高度
pub fn resize(&mut self, width: u32, height: u32) {
self.engine.resize(width as f32, height as f32);
}
/// Set camera position, zoom, and rotation.
/// 设置相机位置、缩放和旋转。
///
/// # Arguments | 参数
/// * `x` - Camera X position | 相机X位置
/// * `y` - Camera Y position | 相机Y位置
/// * `zoom` - Zoom level | 缩放级别
/// * `rotation` - Rotation in radians | 旋转角度(弧度)
#[wasm_bindgen(js_name = setCamera)]
pub fn set_camera(&mut self, x: f32, y: f32, zoom: f32, rotation: f32) {
self.engine.set_camera(x, y, zoom, rotation);
}
/// Get camera state.
/// 获取相机状态。
///
/// # Returns | 返回
/// Array of [x, y, zoom, rotation] | 数组 [x, y, zoom, rotation]
#[wasm_bindgen(js_name = getCamera)]
pub fn get_camera(&self) -> Vec<f32> {
let (x, y, zoom, rotation) = self.engine.get_camera();
vec![x, y, zoom, rotation]
}
feat: 预制体系统与架构改进 (#303) * feat(prefab): 实现预制体系统和编辑器 UX 改进 ## 预制体系统 - 新增 PrefabSerializer: 预制体序列化/反序列化 - 新增 PrefabInstanceComponent: 追踪预制体实例来源和修改 - 新增 PrefabService: 预制体核心服务 - 新增 PrefabLoader: 预制体资产加载器 - 新增预制体命令: Create/Instantiate/Apply/Revert/BreakLink ## 预制体编辑模式 - 支持双击 .prefab 文件进入编辑模式 - 预制体编辑模式工具栏 (保存/退出) - 预制体实例指示器和操作菜单 ## 编辑器 UX 改进 - SceneHierarchy 快捷键: F2 重命名, Ctrl+D 复制, ↑↓ 导航 - 支持双击实体名称内联编辑 - 删除实体时显示子节点数量警告 - 右键菜单添加重命名/复制选项及快捷键提示 - 布局持久化和重置功能 ## Bug 修复 - 修复 editor-runtime 组件类重复导致的 TransformComponent 不识别问题 - 修复 .prefab-name 样式覆盖导致预制体工具栏文字不可见 - 修复 Inspector 资源字段高度不正确问题 * feat(editor): 改进编辑器 UX 交互体验 - ContentBrowser: 加载动画 spinner、搜索高亮、改进空状态设计 - SceneHierarchy: 选中项自动滚动到视图、搜索清除按钮 - PropertyInspector: 输入框本地状态管理、Enter/Escape 键处理 - EntityInspector: 组件折叠状态持久化、属性搜索清除按钮 - Viewport: 变换操作实时数值显示 - 国际化: 添加相关文本 (en/zh) * fix(build): 修复 Web 构建资产加载和编辑器 UX 改进 构建系统修复: - 修复 asset-catalog.json 字段名不匹配 (entries vs assets) - 修复 BrowserFileSystemService 支持两种目录格式 - 修复 bundle 策略检测逻辑 (空对象判断) - 修复 module.json 中 assetExtensions 声明和类型推断 行为树修复: - 修复 BehaviorTreeExecutionSystem 使用 loadAsset 替代 loadAssetByPath - 修复 BehaviorTreeAssetType 常量与 module.json 类型名一致 (behavior-tree) 编辑器 UX 改进: - 构建完成对话框添加"打开文件夹"按钮 - 构建完成对话框样式优化 (圆形图标背景、按钮布局) - SceneHierarchy 响应式布局 (窄窗口自动隐藏 Type 列) - SceneHierarchy 隐藏滚动条 错误追踪: - 添加全局错误处理器写入日志文件 (%TEMP%/esengine-editor-crash.log) - 添加 append_to_log Tauri 命令 * feat(render): 修复 UI 渲染和点击特效系统 ## UI 渲染修复 - 修复 GUID 验证 bug,使用统一的 isValidGUID() 函数 - 修复 UI 渲染顺序随机问题,Rust 端使用 IndexMap 替代 HashMap - Web 运行时添加 assetPathResolver 支持 GUID 解析 - UIInteractableComponent.blockEvents 默认值改为 false ## 点击特效系统 - 新增 ClickFxComponent 和 ClickFxSystem - 支持在点击位置播放粒子效果 - 支持多种触发模式和粒子轮换 ## Camera 系统重构 - CameraSystem 从 ecs-engine-bindgen 移至 camera 包 - 新增 CameraManager 统一管理相机 ## 编辑器改进 - 改进属性面板 UI 交互 - 粒子编辑器面板优化 - Transform 命令系统 * feat(render): 实现 Sorting Layer 系统和 Overlay 渲染层 - 新增 SortingLayerManager 管理排序层级 (Background, Default, Foreground, UI, Overlay) - 实现 ISortable 接口,统一 Sprite、UI、Particle 的排序属性 - 修复粒子 Overlay 层被 UI 遮挡问题:添加独立的 Overlay Pass 在 UI 之后渲染 - 更新粒子资产格式:从 sortingOrder 改为 sortingLayer + orderInLayer - 更新粒子编辑器面板支持新的排序属性 - 优化 UI 渲染系统使用新的排序层级 * feat(ci): 集成 SignPath 代码签名服务 - 添加 SignPath 自动签名工作流(Windows) - 配置 release-editor.yml 支持代码签名 - 将构建改为草稿模式,等待签名完成后发布 - 添加证书文件到 .gitignore 防止泄露 * fix(asset): 修复 Web 构建资产路径解析和全局单例移除 ## 资产路径修复 - 修复 Tauri 本地服务器 `/asset?path=...` 路径解析,正确与 root 目录连接 - BrowserPathResolver 支持两种模式: - 'proxy': 使用 /asset?path=... 格式(编辑器 Run in Browser) - 'direct': 使用直接路径 /assets/path.png(独立 Web 构建) - BrowserRuntime 使用 'direct' 模式,无需 Tauri 代理 ## 架构改进 - 移除全局单例 - 移除 globalAssetManager 导出,改用 AssetManagerToken 依赖注入 - 移除 globalPathResolver 导出,改用 PathResolutionService - 移除 globalPathResolutionService 导出 - ParticleUpdateSystem/ClickFxSystem 通过 setAssetManager() 注入依赖 - EngineService 使用 new AssetManager() 替代全局实例 ## 新增服务 - PathResolutionService: 统一路径解析接口 - RuntimeModeService: 运行时模式查询服务 - SerializationContext: EntityRef 序列化上下文 ## 其他改进 - 完善 ServiceToken 注释说明本地定义的意图 - 导出 BrowserPathResolveMode 类型 * fix(build): 添加 world-streaming composite 设置修复类型检查 * fix(build): 移除 world-streaming 引用避免 composite 冲突 * fix(build): 将 const enum 改为 enum 兼容 isolatedModules * fix(build): 添加缺失的 IAssetManager 导入
2025-12-13 19:44:08 +08:00
/// Convert screen coordinates to world coordinates.
/// 将屏幕坐标转换为世界坐标。
///
/// # Arguments | 参数
/// * `screen_x` - Screen X coordinate (0 = left edge of canvas)
/// * `screen_y` - Screen Y coordinate (0 = top edge of canvas)
///
/// # Returns | 返回
/// Array of [world_x, world_y] | 数组 [world_x, world_y]
#[wasm_bindgen(js_name = screenToWorld)]
pub fn screen_to_world(&self, screen_x: f32, screen_y: f32) -> Vec<f32> {
let (x, y) = self.engine.screen_to_world(screen_x, screen_y);
vec![x, y]
}
/// Convert world coordinates to screen coordinates.
/// 将世界坐标转换为屏幕坐标。
///
/// # Arguments | 参数
/// * `world_x` - World X coordinate
/// * `world_y` - World Y coordinate
///
/// # Returns | 返回
/// Array of [screen_x, screen_y] | 数组 [screen_x, screen_y]
#[wasm_bindgen(js_name = worldToScreen)]
pub fn world_to_screen(&self, world_x: f32, world_y: f32) -> Vec<f32> {
let (x, y) = self.engine.world_to_screen(world_x, world_y);
vec![x, y]
}
/// Set grid visibility.
/// 设置网格可见性。
#[wasm_bindgen(js_name = setShowGrid)]
pub fn set_show_grid(&mut self, show: bool) {
self.engine.set_show_grid(show);
}
/// Set clear color (background color).
/// 设置清除颜色(背景颜色)。
///
/// # Arguments | 参数
/// * `r`, `g`, `b`, `a` - Color components (0.0-1.0) | 颜色分量 (0.0-1.0)
#[wasm_bindgen(js_name = setClearColor)]
pub fn set_clear_color(&mut self, r: f32, g: f32, b: f32, a: f32) {
self.engine.set_clear_color(r, g, b, a);
}
/// Add a rectangle gizmo outline.
/// 添加矩形Gizmo边框。
///
/// # Arguments | 参数
/// * `x` - Center X position | 中心X位置
/// * `y` - Center Y position | 中心Y位置
/// * `width` - Rectangle width | 矩形宽度
/// * `height` - Rectangle height | 矩形高度
/// * `rotation` - Rotation in radians | 旋转角度(弧度)
/// * `origin_x` - Origin X (0-1) | 原点X (0-1)
/// * `origin_y` - Origin Y (0-1) | 原点Y (0-1)
/// * `r`, `g`, `b`, `a` - Color (0.0-1.0) | 颜色
/// * `show_handles` - Whether to show transform handles | 是否显示变换手柄
#[wasm_bindgen(js_name = addGizmoRect)]
pub fn add_gizmo_rect(
&mut self,
x: f32,
y: f32,
width: f32,
height: f32,
rotation: f32,
origin_x: f32,
origin_y: f32,
r: f32,
g: f32,
b: f32,
a: f32,
show_handles: bool,
) {
self.engine.add_gizmo_rect(x, y, width, height, rotation, origin_x, origin_y, r, g, b, a, show_handles);
}
/// Add a circle gizmo outline.
/// 添加圆形Gizmo边框。
#[wasm_bindgen(js_name = addGizmoCircle)]
pub fn add_gizmo_circle(
&mut self,
x: f32,
y: f32,
radius: f32,
r: f32,
g: f32,
b: f32,
a: f32,
) {
self.engine.add_gizmo_circle(x, y, radius, r, g, b, a);
}
/// Add a line gizmo.
/// 添加线条Gizmo。
#[wasm_bindgen(js_name = addGizmoLine)]
pub fn add_gizmo_line(
&mut self,
points: Vec<f32>,
r: f32,
g: f32,
b: f32,
a: f32,
closed: bool,
) {
self.engine.add_gizmo_line(points, r, g, b, a, closed);
}
/// Add a capsule gizmo outline.
/// 添加胶囊Gizmo边框。
#[wasm_bindgen(js_name = addGizmoCapsule)]
pub fn add_gizmo_capsule(
&mut self,
x: f32,
y: f32,
radius: f32,
half_height: f32,
rotation: f32,
r: f32,
g: f32,
b: f32,
a: f32,
) {
self.engine.add_gizmo_capsule(x, y, radius, half_height, rotation, r, g, b, a);
}
/// Set transform tool mode.
/// 设置变换工具模式。
///
/// # Arguments | 参数
/// * `mode` - 0=Select, 1=Move, 2=Rotate, 3=Scale
#[wasm_bindgen(js_name = setTransformMode)]
pub fn set_transform_mode(&mut self, mode: u8) {
self.engine.set_transform_mode(mode);
}
/// Set gizmo visibility.
/// 设置辅助工具可见性。
#[wasm_bindgen(js_name = setShowGizmos)]
pub fn set_show_gizmos(&mut self, show: bool) {
self.engine.set_show_gizmos(show);
}
/// Set editor mode.
/// 设置编辑器模式。
///
/// When false (runtime mode), editor-only UI like grid, gizmos,
/// and axis indicator are automatically hidden.
/// 当为 false运行时模式编辑器专用 UI如网格、gizmos、坐标轴指示器会自动隐藏。
#[wasm_bindgen(js_name = setEditorMode)]
pub fn set_editor_mode(&mut self, is_editor: bool) {
self.engine.set_editor_mode(is_editor);
}
/// Get editor mode.
/// 获取编辑器模式。
#[wasm_bindgen(js_name = isEditorMode)]
pub fn is_editor_mode(&self) -> bool {
self.engine.is_editor()
}
// ===== Multi-viewport API =====
// ===== 多视口 API =====
/// Register a new viewport.
/// 注册新视口。
///
/// # Arguments | 参数
/// * `id` - Unique viewport identifier | 唯一视口标识符
/// * `canvas_id` - HTML canvas element ID | HTML canvas元素ID
#[wasm_bindgen(js_name = registerViewport)]
pub fn register_viewport(&mut self, id: &str, canvas_id: &str) -> std::result::Result<(), JsValue> {
self.engine
.register_viewport(id, canvas_id)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Unregister a viewport.
/// 注销视口。
#[wasm_bindgen(js_name = unregisterViewport)]
pub fn unregister_viewport(&mut self, id: &str) {
self.engine.unregister_viewport(id);
}
/// Set the active viewport.
/// 设置活动视口。
#[wasm_bindgen(js_name = setActiveViewport)]
pub fn set_active_viewport(&mut self, id: &str) -> bool {
self.engine.set_active_viewport(id)
}
/// Set camera for a specific viewport.
/// 为特定视口设置相机。
#[wasm_bindgen(js_name = setViewportCamera)]
pub fn set_viewport_camera(&mut self, viewport_id: &str, x: f32, y: f32, zoom: f32, rotation: f32) {
self.engine.set_viewport_camera(viewport_id, x, y, zoom, rotation);
}
/// Get camera for a specific viewport.
/// 获取特定视口的相机。
#[wasm_bindgen(js_name = getViewportCamera)]
pub fn get_viewport_camera(&self, viewport_id: &str) -> Option<Vec<f32>> {
self.engine
.get_viewport_camera(viewport_id)
.map(|(x, y, zoom, rotation)| vec![x, y, zoom, rotation])
}
/// Set viewport configuration.
/// 设置视口配置。
#[wasm_bindgen(js_name = setViewportConfig)]
pub fn set_viewport_config(&mut self, viewport_id: &str, show_grid: bool, show_gizmos: bool) {
self.engine.set_viewport_config(viewport_id, show_grid, show_gizmos);
}
/// Resize a specific viewport.
/// 调整特定视口大小。
#[wasm_bindgen(js_name = resizeViewport)]
pub fn resize_viewport(&mut self, viewport_id: &str, width: u32, height: u32) {
self.engine.resize_viewport(viewport_id, width, height);
}
/// Render to a specific viewport.
/// 渲染到特定视口。
#[wasm_bindgen(js_name = renderToViewport)]
pub fn render_to_viewport(&mut self, viewport_id: &str) -> std::result::Result<(), JsValue> {
self.engine
.render_to_viewport(viewport_id)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Get all registered viewport IDs.
/// 获取所有已注册的视口ID。
#[wasm_bindgen(js_name = getViewportIds)]
pub fn get_viewport_ids(&self) -> Vec<String> {
self.engine.viewport_ids()
}
feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
// ===== Shader API =====
// ===== 着色器 API =====
/// Compile and register a custom shader.
/// 编译并注册自定义着色器。
///
/// # Arguments | 参数
/// * `vertex_source` - Vertex shader GLSL source | 顶点着色器GLSL源代码
/// * `fragment_source` - Fragment shader GLSL source | 片段着色器GLSL源代码
///
/// # Returns | 返回
/// The shader ID for referencing this shader | 用于引用此着色器的ID
#[wasm_bindgen(js_name = compileShader)]
pub fn compile_shader(
&mut self,
vertex_source: &str,
fragment_source: &str,
) -> std::result::Result<u32, JsValue> {
self.engine
.compile_shader(vertex_source, fragment_source)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Compile a shader with a specific ID.
/// 使用特定ID编译着色器。
#[wasm_bindgen(js_name = compileShaderWithId)]
pub fn compile_shader_with_id(
&mut self,
shader_id: u32,
vertex_source: &str,
fragment_source: &str,
) -> std::result::Result<(), JsValue> {
self.engine
.compile_shader_with_id(shader_id, vertex_source, fragment_source)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
/// Check if a shader exists.
/// 检查着色器是否存在。
#[wasm_bindgen(js_name = hasShader)]
pub fn has_shader(&self, shader_id: u32) -> bool {
self.engine.has_shader(shader_id)
}
/// Remove a shader.
/// 移除着色器。
#[wasm_bindgen(js_name = removeShader)]
pub fn remove_shader(&mut self, shader_id: u32) -> bool {
self.engine.remove_shader(shader_id)
}
// ===== Material API =====
// ===== 材质 API =====
/// Create and register a new material.
/// 创建并注册新材质。
///
/// # Arguments | 参数
/// * `name` - Material name for debugging | 材质名称(用于调试)
/// * `shader_id` - Shader ID to use | 使用的着色器ID
/// * `blend_mode` - Blend mode: 0=None, 1=Alpha, 2=Additive, 3=Multiply, 4=Screen, 5=PremultipliedAlpha
///
/// # Returns | 返回
/// The material ID for referencing this material | 用于引用此材质的ID
#[wasm_bindgen(js_name = createMaterial)]
pub fn create_material(
&mut self,
name: &str,
shader_id: u32,
blend_mode: u8,
) -> u32 {
self.engine.create_material(name, shader_id, blend_mode)
}
/// Create a material with a specific ID.
/// 使用特定ID创建材质。
#[wasm_bindgen(js_name = createMaterialWithId)]
pub fn create_material_with_id(
&mut self,
material_id: u32,
name: &str,
shader_id: u32,
blend_mode: u8,
) {
self.engine.create_material_with_id(material_id, name, shader_id, blend_mode);
}
/// Check if a material exists.
/// 检查材质是否存在。
#[wasm_bindgen(js_name = hasMaterial)]
pub fn has_material(&self, material_id: u32) -> bool {
self.engine.has_material(material_id)
}
/// Remove a material.
/// 移除材质。
#[wasm_bindgen(js_name = removeMaterial)]
pub fn remove_material(&mut self, material_id: u32) -> bool {
self.engine.remove_material(material_id)
}
/// Set a material's float uniform.
/// 设置材质的浮点uniform。
#[wasm_bindgen(js_name = setMaterialFloat)]
pub fn set_material_float(&mut self, material_id: u32, name: &str, value: f32) -> bool {
self.engine.set_material_float(material_id, name, value)
}
/// Set a material's vec2 uniform.
/// 设置材质的vec2 uniform。
#[wasm_bindgen(js_name = setMaterialVec2)]
pub fn set_material_vec2(&mut self, material_id: u32, name: &str, x: f32, y: f32) -> bool {
self.engine.set_material_vec2(material_id, name, x, y)
}
/// Set a material's vec3 uniform.
/// 设置材质的vec3 uniform。
#[wasm_bindgen(js_name = setMaterialVec3)]
pub fn set_material_vec3(&mut self, material_id: u32, name: &str, x: f32, y: f32, z: f32) -> bool {
self.engine.set_material_vec3(material_id, name, x, y, z)
}
/// Set a material's vec4 uniform (also used for colors).
/// 设置材质的vec4 uniform也用于颜色
#[wasm_bindgen(js_name = setMaterialVec4)]
pub fn set_material_vec4(&mut self, material_id: u32, name: &str, x: f32, y: f32, z: f32, w: f32) -> bool {
self.engine.set_material_vec4(material_id, name, x, y, z, w)
}
/// Set a material's color uniform (RGBA, 0.0-1.0).
/// 设置材质的颜色uniformRGBA0.0-1.0)。
#[wasm_bindgen(js_name = setMaterialColor)]
pub fn set_material_color(&mut self, material_id: u32, name: &str, r: f32, g: f32, b: f32, a: f32) -> bool {
self.engine.set_material_color(material_id, name, r, g, b, a)
}
/// Set a material's blend mode.
/// 设置材质的混合模式。
///
/// # Arguments | 参数
/// * `blend_mode` - 0=None, 1=Alpha, 2=Additive, 3=Multiply, 4=Screen, 5=PremultipliedAlpha
#[wasm_bindgen(js_name = setMaterialBlendMode)]
pub fn set_material_blend_mode(&mut self, material_id: u32, blend_mode: u8) -> bool {
self.engine.set_material_blend_mode(material_id, blend_mode)
}
feat: 预制体系统与架构改进 (#303) * feat(prefab): 实现预制体系统和编辑器 UX 改进 ## 预制体系统 - 新增 PrefabSerializer: 预制体序列化/反序列化 - 新增 PrefabInstanceComponent: 追踪预制体实例来源和修改 - 新增 PrefabService: 预制体核心服务 - 新增 PrefabLoader: 预制体资产加载器 - 新增预制体命令: Create/Instantiate/Apply/Revert/BreakLink ## 预制体编辑模式 - 支持双击 .prefab 文件进入编辑模式 - 预制体编辑模式工具栏 (保存/退出) - 预制体实例指示器和操作菜单 ## 编辑器 UX 改进 - SceneHierarchy 快捷键: F2 重命名, Ctrl+D 复制, ↑↓ 导航 - 支持双击实体名称内联编辑 - 删除实体时显示子节点数量警告 - 右键菜单添加重命名/复制选项及快捷键提示 - 布局持久化和重置功能 ## Bug 修复 - 修复 editor-runtime 组件类重复导致的 TransformComponent 不识别问题 - 修复 .prefab-name 样式覆盖导致预制体工具栏文字不可见 - 修复 Inspector 资源字段高度不正确问题 * feat(editor): 改进编辑器 UX 交互体验 - ContentBrowser: 加载动画 spinner、搜索高亮、改进空状态设计 - SceneHierarchy: 选中项自动滚动到视图、搜索清除按钮 - PropertyInspector: 输入框本地状态管理、Enter/Escape 键处理 - EntityInspector: 组件折叠状态持久化、属性搜索清除按钮 - Viewport: 变换操作实时数值显示 - 国际化: 添加相关文本 (en/zh) * fix(build): 修复 Web 构建资产加载和编辑器 UX 改进 构建系统修复: - 修复 asset-catalog.json 字段名不匹配 (entries vs assets) - 修复 BrowserFileSystemService 支持两种目录格式 - 修复 bundle 策略检测逻辑 (空对象判断) - 修复 module.json 中 assetExtensions 声明和类型推断 行为树修复: - 修复 BehaviorTreeExecutionSystem 使用 loadAsset 替代 loadAssetByPath - 修复 BehaviorTreeAssetType 常量与 module.json 类型名一致 (behavior-tree) 编辑器 UX 改进: - 构建完成对话框添加"打开文件夹"按钮 - 构建完成对话框样式优化 (圆形图标背景、按钮布局) - SceneHierarchy 响应式布局 (窄窗口自动隐藏 Type 列) - SceneHierarchy 隐藏滚动条 错误追踪: - 添加全局错误处理器写入日志文件 (%TEMP%/esengine-editor-crash.log) - 添加 append_to_log Tauri 命令 * feat(render): 修复 UI 渲染和点击特效系统 ## UI 渲染修复 - 修复 GUID 验证 bug,使用统一的 isValidGUID() 函数 - 修复 UI 渲染顺序随机问题,Rust 端使用 IndexMap 替代 HashMap - Web 运行时添加 assetPathResolver 支持 GUID 解析 - UIInteractableComponent.blockEvents 默认值改为 false ## 点击特效系统 - 新增 ClickFxComponent 和 ClickFxSystem - 支持在点击位置播放粒子效果 - 支持多种触发模式和粒子轮换 ## Camera 系统重构 - CameraSystem 从 ecs-engine-bindgen 移至 camera 包 - 新增 CameraManager 统一管理相机 ## 编辑器改进 - 改进属性面板 UI 交互 - 粒子编辑器面板优化 - Transform 命令系统 * feat(render): 实现 Sorting Layer 系统和 Overlay 渲染层 - 新增 SortingLayerManager 管理排序层级 (Background, Default, Foreground, UI, Overlay) - 实现 ISortable 接口,统一 Sprite、UI、Particle 的排序属性 - 修复粒子 Overlay 层被 UI 遮挡问题:添加独立的 Overlay Pass 在 UI 之后渲染 - 更新粒子资产格式:从 sortingOrder 改为 sortingLayer + orderInLayer - 更新粒子编辑器面板支持新的排序属性 - 优化 UI 渲染系统使用新的排序层级 * feat(ci): 集成 SignPath 代码签名服务 - 添加 SignPath 自动签名工作流(Windows) - 配置 release-editor.yml 支持代码签名 - 将构建改为草稿模式,等待签名完成后发布 - 添加证书文件到 .gitignore 防止泄露 * fix(asset): 修复 Web 构建资产路径解析和全局单例移除 ## 资产路径修复 - 修复 Tauri 本地服务器 `/asset?path=...` 路径解析,正确与 root 目录连接 - BrowserPathResolver 支持两种模式: - 'proxy': 使用 /asset?path=... 格式(编辑器 Run in Browser) - 'direct': 使用直接路径 /assets/path.png(独立 Web 构建) - BrowserRuntime 使用 'direct' 模式,无需 Tauri 代理 ## 架构改进 - 移除全局单例 - 移除 globalAssetManager 导出,改用 AssetManagerToken 依赖注入 - 移除 globalPathResolver 导出,改用 PathResolutionService - 移除 globalPathResolutionService 导出 - ParticleUpdateSystem/ClickFxSystem 通过 setAssetManager() 注入依赖 - EngineService 使用 new AssetManager() 替代全局实例 ## 新增服务 - PathResolutionService: 统一路径解析接口 - RuntimeModeService: 运行时模式查询服务 - SerializationContext: EntityRef 序列化上下文 ## 其他改进 - 完善 ServiceToken 注释说明本地定义的意图 - 导出 BrowserPathResolveMode 类型 * fix(build): 添加 world-streaming composite 设置修复类型检查 * fix(build): 移除 world-streaming 引用避免 composite 冲突 * fix(build): 将 const enum 改为 enum 兼容 isolatedModules * fix(build): 添加缺失的 IAssetManager 导入
2025-12-13 19:44:08 +08:00
// ===== Texture Cache API =====
// ===== 纹理缓存 API =====
/// Clear the texture path cache.
/// 清除纹理路径缓存。
///
/// This should be called when restoring scene snapshots to ensure
/// textures are reloaded with correct IDs.
/// 在恢复场景快照时应调用此方法以确保纹理使用正确的ID重新加载。
#[wasm_bindgen(js_name = clearTexturePathCache)]
pub fn clear_texture_path_cache(&mut self) {
self.engine.clear_texture_path_cache();
}
/// Clear all textures and reset state.
/// 清除所有纹理并重置状态。
///
/// This removes all loaded textures from GPU memory and resets
/// the ID counter. Use with caution as all texture references
/// will become invalid.
/// 这会从GPU内存中移除所有已加载的纹理并重置ID计数器。
/// 请谨慎使用,因为所有纹理引用都将变得无效。
#[wasm_bindgen(js_name = clearAllTextures)]
pub fn clear_all_textures(&mut self) {
self.engine.clear_all_textures();
}
}