feat: 集成Rust WASM渲染引擎与TypeScript ECS框架 (#228)

* feat: 集成Rust WASM渲染引擎与TypeScript ECS框架

* feat: 增强编辑器UI功能与跨平台支持

* fix: 修复CI测试和类型检查问题

* fix: 修复CI问题并提高测试覆盖率

* fix: 修复CI问题并提高测试覆盖率
This commit is contained in:
YHH
2025-11-21 10:03:18 +08:00
committed by GitHub
parent 8b9616837d
commit a768b890fd
107 changed files with 10221 additions and 477 deletions

View File

@@ -0,0 +1,51 @@
//! Platform abstraction layer.
//! 平台抽象层。
//!
//! Provides abstractions for platform-specific functionality.
//! 提供平台特定功能的抽象。
mod web;
pub use web::WebPlatform;
/// Platform capabilities and information.
/// 平台能力和信息。
#[derive(Debug, Clone)]
pub struct PlatformInfo {
/// Platform name.
/// 平台名称。
pub name: String,
/// Whether WebGL2 is supported.
/// 是否支持WebGL2。
pub webgl2_supported: bool,
/// Whether touch input is supported.
/// 是否支持触摸输入。
pub touch_supported: bool,
/// Device pixel ratio.
/// 设备像素比。
pub pixel_ratio: f32,
/// Screen width.
/// 屏幕宽度。
pub screen_width: u32,
/// Screen height.
/// 屏幕高度。
pub screen_height: u32,
}
impl Default for PlatformInfo {
fn default() -> Self {
Self {
name: "Unknown".to_string(),
webgl2_supported: false,
touch_supported: false,
pixel_ratio: 1.0,
screen_width: 0,
screen_height: 0,
}
}
}

View File

@@ -0,0 +1,146 @@
//! Web platform implementation.
//! Web平台实现。
use wasm_bindgen::JsCast;
use web_sys::Window;
use super::PlatformInfo;
/// Web platform utilities.
/// Web平台工具。
pub struct WebPlatform;
impl WebPlatform {
/// Get platform information.
/// 获取平台信息。
pub fn get_info() -> PlatformInfo {
let window = match web_sys::window() {
Some(w) => w,
None => return PlatformInfo::default(),
};
let navigator = window.navigator();
let user_agent = navigator.user_agent().unwrap_or_default();
// Detect platform name | 检测平台名称
let name = Self::detect_platform_name(&user_agent);
// Check WebGL2 support | 检查WebGL2支持
let webgl2_supported = Self::check_webgl2_support(&window);
// Check touch support | 检查触摸支持
let touch_supported = Self::check_touch_support(&window);
// Get device pixel ratio | 获取设备像素比
let pixel_ratio = window.device_pixel_ratio() as f32;
// Get screen size | 获取屏幕尺寸
let screen = window.screen().ok();
let (screen_width, screen_height) = screen
.map(|s| {
(
s.width().unwrap_or(0) as u32,
s.height().unwrap_or(0) as u32,
)
})
.unwrap_or((0, 0));
PlatformInfo {
name,
webgl2_supported,
touch_supported,
pixel_ratio,
screen_width,
screen_height,
}
}
/// Detect platform name from user agent.
/// 从用户代理检测平台名称。
fn detect_platform_name(user_agent: &str) -> String {
let ua = user_agent.to_lowercase();
if ua.contains("micromessenger") {
"WeChat MiniGame".to_string()
} else if ua.contains("bytedance") || ua.contains("toutiao") {
"ByteDance MiniGame".to_string()
} else if ua.contains("alipay") {
"Alipay MiniGame".to_string()
} else if ua.contains("iphone") || ua.contains("ipad") {
"iOS Web".to_string()
} else if ua.contains("android") {
"Android Web".to_string()
} else if ua.contains("windows") {
"Windows Web".to_string()
} else if ua.contains("macintosh") {
"macOS Web".to_string()
} else {
"Web".to_string()
}
}
/// Check if WebGL2 is supported.
/// 检查是否支持WebGL2。
fn check_webgl2_support(window: &Window) -> bool {
let document = match window.document() {
Some(d) => d,
None => return false,
};
let canvas = match document.create_element("canvas") {
Ok(c) => c,
Err(_) => return false,
};
let canvas = match canvas.dyn_into::<web_sys::HtmlCanvasElement>() {
Ok(c) => c,
Err(_) => return false,
};
canvas.get_context("webgl2").ok().flatten().is_some()
}
/// Check if touch input is supported.
/// 检查是否支持触摸输入。
fn check_touch_support(window: &Window) -> bool {
// Check for touch events | 检查触摸事件
let has_touch_event = js_sys::Reflect::has(
window,
&wasm_bindgen::JsValue::from_str("ontouchstart"),
)
.unwrap_or(false);
if has_touch_event {
return true;
}
// Check navigator.maxTouchPoints | 检查navigator.maxTouchPoints
let navigator = window.navigator();
navigator.max_touch_points() > 0
}
/// Request animation frame.
/// 请求动画帧。
pub fn request_animation_frame(callback: &wasm_bindgen::closure::Closure<dyn FnMut()>) -> i32 {
let window = web_sys::window().expect("No window found");
window
.request_animation_frame(callback.as_ref().unchecked_ref())
.expect("Failed to request animation frame")
}
/// Get current timestamp in milliseconds.
/// 获取当前时间戳(毫秒)。
pub fn now() -> f64 {
let window = web_sys::window().expect("No window found");
window
.performance()
.expect("No performance object")
.now()
}
/// Log a message to the console.
/// 向控制台输出消息。
pub fn console_log(message: &str) {
web_sys::console::log_1(&wasm_bindgen::JsValue::from_str(message));
}
}