core核心rust实现

This commit is contained in:
YHH
2025-08-18 20:46:47 +08:00
parent e4e38ee4e6
commit bdbef0bd0d
42 changed files with 17157 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
[package]
name = "ecs-core-rust"
version = "0.0.1"
edition = "2021"
description = "基于Rust和WebAssembly的高性能ECS框架核心实现"
authors = ["yhh"]
license = "MIT"
repository = "https://github.com/esengine/ecs-framework.git"
keywords = ["ecs", "entity-component-system", "game-engine", "wasm", "webassembly"]
[package.metadata.wasm-pack.profile.release.wasm-bindgen]
out-name = "ecs-core-rust"
[package.metadata.wasm-pack]
name = "@esengine/ecs-framework-wasm"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
js-sys = "0.3"
web-sys = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.4"
serde_json = "1.0"
rustc-hash = "1.1"
console_error_panic_hook = { version = "0.1.7", optional = true }
[features]
default = ["console_error_panic_hook"]
[package.metadata.wasm-pack.profile.release]
wasm-opt = false

View File

@@ -0,0 +1,41 @@
@echo off
setlocal enabledelayedexpansion
REM 构建WASM到core库的脚本 (Windows版本)
echo 🚀 开始构建 WASM 到 core 库...
REM 确保在正确的目录
cd /d "%~dp0"
REM 确保目标目录存在
if not exist "..\core\wasm" mkdir "..\core\wasm"
REM 构建WASM包
echo 📦 构建 WASM 包...
wasm-pack build --target web --out-dir temp-pkg
REM 检查构建是否成功
if not exist "temp-pkg" (
echo ❌ WASM构建失败
exit /b 1
)
REM 复制文件到core库
echo 📁 复制文件到 core\wasm...
copy "temp-pkg\*.wasm" "..\core\wasm\" >nul
copy "temp-pkg\*.js" "..\core\wasm\" >nul
copy "temp-pkg\*.ts" "..\core\wasm\" >nul
REM 清理临时文件
echo 🧹 清理临时文件...
rmdir /s /q temp-pkg
echo ✅ 构建完成WASM文件已输出到 packages\core\wasm\
echo.
echo 文件列表:
dir "..\core\wasm\"
echo.
echo 🎯 现在可以在 TypeScript 中直接导入 WASM 模块了!
pause

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# 构建WASM到core库的脚本
set -e
echo "🚀 开始构建 WASM 到 core 库..."
# 确保在正确的目录
cd "$(dirname "$0")"
# 确保目标目录存在
mkdir -p ../core/wasm
# 构建WASM包
echo "📦 构建 WASM 包..."
wasm-pack build --target web --out-dir temp-pkg
# 检查构建是否成功
if [ ! -d "temp-pkg" ]; then
echo "❌ WASM构建失败"
exit 1
fi
# 复制文件到core库排除不需要的文件
echo "📁 复制文件到 core/wasm..."
cp temp-pkg/*.wasm ../core/wasm/
cp temp-pkg/*.js ../core/wasm/
cp temp-pkg/*.ts ../core/wasm/
# 清理临时文件
echo "🧹 清理临时文件..."
rm -rf temp-pkg
echo "✅ 构建完成WASM文件已输出到 packages/core/wasm/"
echo ""
echo "文件列表:"
ls -la ../core/wasm/
echo ""
echo "🎯 现在可以在 TypeScript 中直接导入 WASM 模块了!"

View File

@@ -0,0 +1,89 @@
# Windows PowerShell构建脚本
param(
[switch]$Install,
[switch]$Help
)
if ($Help) {
Write-Host "ECS Core Rust WASM构建脚本"
Write-Host ""
Write-Host "用法:"
Write-Host " .\build.ps1 # 构建WASM包"
Write-Host " .\build.ps1 -Install # 安装依赖并构建"
Write-Host " .\build.ps1 -Help # 显示帮助"
Write-Host ""
Write-Host "环境要求:"
Write-Host " - Rust (rustup)"
Write-Host " - wasm-pack"
exit
}
Write-Host "开始构建Rust WASM包..." -ForegroundColor Green
# 检查Rust是否安装
if (!(Get-Command cargo -ErrorAction SilentlyContinue)) {
Write-Host "错误: 未找到cargo命令" -ForegroundColor Red
if ($Install) {
Write-Host "正在安装Rust..." -ForegroundColor Yellow
# 下载并运行Rust安装程序
Invoke-RestMethod -Uri https://win.rustup.rs/ -OutFile rustup-init.exe
.\rustup-init.exe -y --default-toolchain stable
Remove-Item rustup-init.exe
# 重新加载PATH
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User")
# 添加Cargo到当前会话的PATH
if (Test-Path "$env:USERPROFILE\.cargo\bin") {
$env:PATH += ";$env:USERPROFILE\.cargo\bin"
}
} else {
Write-Host "请先安装Rust: https://rustup.rs/" -ForegroundColor Red
Write-Host "或者使用 -Install 参数自动安装" -ForegroundColor Yellow
exit 1
}
}
# 检查wasm-pack是否安装
if (!(Get-Command wasm-pack -ErrorAction SilentlyContinue)) {
Write-Host "未找到wasm-pack正在安装..." -ForegroundColor Yellow
if ($Install -or (Read-Host "是否安装wasm-pack? (y/N)").ToLower() -eq 'y') {
# 使用cargo安装wasm-pack
cargo install wasm-pack
} else {
Write-Host "请先安装wasm-pack: https://rustwasm.github.io/wasm-pack/installer/" -ForegroundColor Red
exit 1
}
}
# 添加wasm32目标
Write-Host "添加wasm32目标..." -ForegroundColor Yellow
rustup target add wasm32-unknown-unknown
# 构建WASM包
Write-Host "构建WASM包..." -ForegroundColor Yellow
$env:RUST_LOG = "warn" # 减少日志输出
try {
wasm-pack build --target web --out-dir ..\core\src\wasm --out-name ecs-core-rust
if ($LASTEXITCODE -eq 0) {
Write-Host "构建成功!" -ForegroundColor Green
Write-Host "生成的文件位于: ..\core\src\wasm\" -ForegroundColor Green
# 显示生成的文件
Write-Host "`n生成的文件:" -ForegroundColor Cyan
Get-ChildItem ..\core\src\wasm\ | ForEach-Object {
Write-Host " $($_.Name)" -ForegroundColor Gray
}
} else {
Write-Host "构建失败,退出码: $LASTEXITCODE" -ForegroundColor Red
exit $LASTEXITCODE
}
} catch {
Write-Host "构建过程中发生错误: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
Write-Host "`n构建完成!" -ForegroundColor Green
Write-Host "现在可以在TypeScript中使用WASM版本的ECS核心了。" -ForegroundColor Green

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# Linux/macOS构建脚本
print_help() {
echo "ECS Core Rust WASM构建脚本"
echo ""
echo "用法:"
echo " ./build.sh # 构建WASM包"
echo " ./build.sh --install # 安装依赖并构建"
echo " ./build.sh --help # 显示帮助"
echo ""
echo "环境要求:"
echo " - Rust (rustup)"
echo " - wasm-pack"
}
# 解析参数
INSTALL=false
for arg in "$@"; do
case $arg in
--install)
INSTALL=true
shift
;;
--help)
print_help
exit 0
;;
*)
echo "未知参数: $arg"
print_help
exit 1
;;
esac
done
echo "开始构建Rust WASM包..."
# 检查Rust是否安装
if ! command -v cargo &> /dev/null; then
echo "错误: 未找到cargo命令"
if [ "$INSTALL" = true ]; then
echo "正在安装Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.cargo/env
else
echo "请先安装Rust: https://rustup.rs/"
echo "或者使用 --install 参数自动安装"
exit 1
fi
fi
# 确保环境变量加载
if [ -f ~/.cargo/env ]; then
source ~/.cargo/env
fi
# 检查wasm-pack是否安装
if ! command -v wasm-pack &> /dev/null; then
echo "未找到wasm-pack正在安装..."
if [ "$INSTALL" = true ] || { echo "是否安装wasm-pack? (y/N)"; read -r response; [ "$response" = "y" ] || [ "$response" = "Y" ]; }; then
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
else
echo "请先安装wasm-pack: https://rustwasm.github.io/wasm-pack/installer/"
exit 1
fi
fi
# 添加wasm32目标
echo "添加wasm32目标..."
rustup target add wasm32-unknown-unknown
# 构建WASM包
echo "构建WASM包..."
export RUST_LOG=warn # 减少日志输出
if wasm-pack build --target web --out-dir ../core/src/wasm --out-name ecs-core-rust; then
echo "构建成功!"
echo "生成的文件位于: ../core/src/wasm/"
# 显示生成的文件
echo -e "\n生成的文件:"
ls -la ../core/src/wasm/ | grep -v '^d' | awk '{print " " $9}' | grep -v '^$'
else
echo "构建失败,退出码: $?"
exit 1
fi
echo -e "\n构建完成!"
echo "现在可以在TypeScript中使用WASM版本的ECS核心了。"

View File

@@ -0,0 +1,758 @@
use crate::utils::ComponentType;
use rustc_hash::FxHashMap;
use std::collections::HashSet;
/**
* 原型标识符
* 基于组件类型组合生成的唯一标识符
*/
pub type ArchetypeId = String;
/**
* 原型数据结构
* 将具有相同组件组合的实体分组存储
*/
#[derive(Debug, Clone)]
pub struct Archetype {
/// 原型唯一标识符
pub id: ArchetypeId,
/// 包含的组件类型集合
pub component_types: Vec<ComponentType>,
/// 属于该原型的实体列表
pub entities: Vec<u32>,
/// 原型创建时间(毫秒时间戳)
pub created_at: u64,
/// 最后更新时间(毫秒时间戳)
pub updated_at: u64,
/// 组件类型的位掩码(快速匹配)
pub component_mask: u64,
}
impl Archetype {
/**
* 创建新的原型
*/
pub fn new(component_types: Vec<ComponentType>) -> Self {
let id = Self::generate_id(&component_types);
let component_mask = Self::calculate_mask(&component_types);
let now = current_timestamp();
Self {
id,
component_types,
entities: Vec::new(),
created_at: now,
updated_at: now,
component_mask,
}
}
/**
* 生成原型ID
*/
fn generate_id(component_types: &[ComponentType]) -> ArchetypeId {
let mut sorted_types = component_types.to_vec();
sorted_types.sort_by_key(|t| format!("{:?}", t));
// 使用组件类型的哈希值组合生成ID
let combined = sorted_types.iter()
.map(|t| format!("{:?}", t))
.collect::<Vec<_>>()
.join("|");
format!("archetype_{:x}", hash_string(&combined))
}
/**
* 计算组件类型的位掩码
*/
fn calculate_mask(component_types: &[ComponentType]) -> u64 {
// 简化实现使用组件类型哈希的前64位作为掩码
let mut mask = 0u64;
for (i, component_type) in component_types.iter().enumerate() {
if i >= 64 { break; } // 最多支持64种组件类型的掩码
let type_hash = hash_component_type(*component_type);
mask |= 1u64 << (type_hash % 64);
}
mask
}
/**
* 添加实体到原型
*/
pub fn add_entity(&mut self, entity_id: u32) {
if !self.entities.contains(&entity_id) {
self.entities.push(entity_id);
self.updated_at = current_timestamp();
}
}
/**
* 从原型中移除实体
*/
pub fn remove_entity(&mut self, entity_id: u32) -> bool {
if let Some(pos) = self.entities.iter().position(|&id| id == entity_id) {
self.entities.remove(pos);
self.updated_at = current_timestamp();
true
} else {
false
}
}
/**
* 检查原型是否包含指定组件类型
*/
pub fn contains_component(&self, component_type: ComponentType) -> bool {
self.component_types.contains(&component_type)
}
/**
* 检查原型是否包含所有指定的组件类型
*/
pub fn contains_all_components(&self, component_types: &[ComponentType]) -> bool {
component_types.iter().all(|t| self.contains_component(*t))
}
/**
* 检查原型是否包含任意一个指定的组件类型
*/
pub fn contains_any_component(&self, component_types: &[ComponentType]) -> bool {
component_types.iter().any(|t| self.contains_component(*t))
}
/**
* 获取实体数量
*/
pub fn entity_count(&self) -> usize {
self.entities.len()
}
/**
* 检查原型是否为空
*/
pub fn is_empty(&self) -> bool {
self.entities.is_empty()
}
}
/**
* 原型查询结果
*/
#[derive(Debug)]
pub struct ArchetypeQueryResult {
/// 匹配的原型列表
pub archetypes: Vec<Archetype>,
/// 所有匹配实体的总数
pub total_entities: usize,
/// 查询执行时间(毫秒)
pub execution_time: f64,
/// 是否使用了缓存
pub from_cache: bool,
}
/**
* 原型查询统计信息
*/
#[derive(Debug, Default)]
pub struct ArchetypeSystemStats {
/// 总原型数量
pub total_archetypes: usize,
/// 总实体数量
pub total_entities: usize,
/// 平均每个原型的实体数量
pub average_entities_per_archetype: f64,
/// 查询次数
pub total_queries: u32,
/// 缓存命中次数
pub cache_hits: u32,
/// 缓存命中率
pub cache_hit_rate: f32,
/// 内存使用量(估算)
pub memory_usage_bytes: usize,
}
/**
* 原型系统
*
* 根据实体的组件组合将实体分组到不同的原型中,提供高效的查询性能。
* 这是现代ECS的核心优化技术之一。
*/
pub struct ArchetypeSystem {
/// 所有原型的映射表ID -> 原型)
archetypes: FxHashMap<ArchetypeId, Archetype>,
/// 实体到原型的映射
entity_to_archetype: FxHashMap<u32, ArchetypeId>,
/// 组件类型到原型集合的映射(用于快速查找)
component_to_archetypes: FxHashMap<ComponentType, HashSet<ArchetypeId>>,
/// 查询缓存
query_cache: FxHashMap<String, CachedQueryResult>,
/// 缓存配置
cache_timeout_ms: u64,
max_cache_size: usize,
/// 统计信息
stats: ArchetypeSystemStats,
}
/**
* 缓存查询结果
*/
struct CachedQueryResult {
result: ArchetypeQueryResult,
timestamp: u64,
}
impl ArchetypeSystem {
/**
* 创建新的原型系统
*/
pub fn new() -> Self {
Self {
archetypes: FxHashMap::default(),
entity_to_archetype: FxHashMap::default(),
component_to_archetypes: FxHashMap::default(),
query_cache: FxHashMap::default(),
cache_timeout_ms: 5000, // 5秒缓存超时
max_cache_size: 100,
stats: ArchetypeSystemStats::default(),
}
}
/**
* 设置缓存配置
*/
pub fn configure_cache(&mut self, timeout_ms: u64, max_size: usize) {
self.cache_timeout_ms = timeout_ms;
self.max_cache_size = max_size;
}
/**
* 添加实体到原型系统
*/
pub fn add_entity(&mut self, entity_id: u32, component_types: Vec<ComponentType>) {
if component_types.is_empty() {
return; // 不处理没有组件的实体
}
let archetype_id = Archetype::generate_id(&component_types);
// 如果原型不存在,创建新原型
if !self.archetypes.contains_key(&archetype_id) {
let archetype = Archetype::new(component_types.clone());
self.create_archetype(archetype);
}
// 添加实体到原型
if let Some(archetype) = self.archetypes.get_mut(&archetype_id) {
archetype.add_entity(entity_id);
}
// 更新实体到原型的映射
if let Some(old_archetype_id) = self.entity_to_archetype.get(&entity_id).cloned() {
// 如果实体已存在于其他原型中,先移除
if old_archetype_id != archetype_id {
self.remove_entity_from_archetype(entity_id, &old_archetype_id);
}
}
self.entity_to_archetype.insert(entity_id, archetype_id);
// 清空查询缓存(因为原型变化了)
self.invalidate_query_cache();
}
/**
* 从原型系统中移除实体
*/
pub fn remove_entity(&mut self, entity_id: u32) -> bool {
if let Some(archetype_id) = self.entity_to_archetype.remove(&entity_id) {
let success = self.remove_entity_from_archetype(entity_id, &archetype_id);
if success {
self.invalidate_query_cache();
// 如果原型变空了,可以考虑清理(但这里保留空原型以提高性能)
// 实际生产中可能需要定期清理空原型
}
success
} else {
false
}
}
/**
* 实体组件发生变化时更新原型
*/
pub fn update_entity_components(&mut self, entity_id: u32, new_component_types: Vec<ComponentType>) {
// 先移除实体,再重新添加
self.remove_entity(entity_id);
if !new_component_types.is_empty() {
self.add_entity(entity_id, new_component_types);
}
}
/**
* 查询包含所有指定组件的原型
*/
pub fn query_all_components(&mut self, component_types: &[ComponentType]) -> ArchetypeQueryResult {
let cache_key = format!("all:{:?}", component_types);
// 检查缓存
if let Some(cached) = self.get_cached_result(&cache_key) {
self.stats.cache_hits += 1;
self.stats.total_queries += 1;
return cached;
}
let start_time = current_timestamp_f64();
let mut matching_archetypes = Vec::new();
let mut total_entities = 0;
for archetype in self.archetypes.values() {
if archetype.contains_all_components(component_types) {
total_entities += archetype.entity_count();
matching_archetypes.push(archetype.clone());
}
}
let execution_time = current_timestamp_f64() - start_time;
let result = ArchetypeQueryResult {
archetypes: matching_archetypes,
total_entities,
execution_time,
from_cache: false,
};
// 缓存结果
self.cache_query_result(cache_key, &result);
self.stats.total_queries += 1;
result
}
/**
* 查询包含任意指定组件的原型
*/
pub fn query_any_component(&mut self, component_types: &[ComponentType]) -> ArchetypeQueryResult {
let cache_key = format!("any:{:?}", component_types);
if let Some(cached) = self.get_cached_result(&cache_key) {
self.stats.cache_hits += 1;
self.stats.total_queries += 1;
return cached;
}
let start_time = current_timestamp_f64();
let mut matching_archetypes = Vec::new();
let mut total_entities = 0;
for archetype in self.archetypes.values() {
if archetype.contains_any_component(component_types) {
total_entities += archetype.entity_count();
matching_archetypes.push(archetype.clone());
}
}
let execution_time = current_timestamp_f64() - start_time;
let result = ArchetypeQueryResult {
archetypes: matching_archetypes,
total_entities,
execution_time,
from_cache: false,
};
self.cache_query_result(cache_key, &result);
self.stats.total_queries += 1;
result
}
/**
* 根据组件掩码查询原型
*/
pub fn query_by_mask(&mut self, component_mask: u64) -> ArchetypeQueryResult {
let cache_key = format!("mask:{}", component_mask);
if let Some(cached) = self.get_cached_result(&cache_key) {
self.stats.cache_hits += 1;
self.stats.total_queries += 1;
return cached;
}
let start_time = current_timestamp_f64();
let mut matching_archetypes = Vec::new();
let mut total_entities = 0;
for archetype in self.archetypes.values() {
if (archetype.component_mask & component_mask) == component_mask {
total_entities += archetype.entity_count();
matching_archetypes.push(archetype.clone());
}
}
let execution_time = current_timestamp_f64() - start_time;
let result = ArchetypeQueryResult {
archetypes: matching_archetypes,
total_entities,
execution_time,
from_cache: false,
};
self.cache_query_result(cache_key, &result);
self.stats.total_queries += 1;
result
}
/**
* 获取实体所属的原型
*/
pub fn get_entity_archetype(&self, entity_id: u32) -> Option<&Archetype> {
if let Some(archetype_id) = self.entity_to_archetype.get(&entity_id) {
self.archetypes.get(archetype_id)
} else {
None
}
}
/**
* 获取所有原型的列表
*/
pub fn get_all_archetypes(&self) -> Vec<&Archetype> {
self.archetypes.values().collect()
}
/**
* 获取统计信息
*/
pub fn get_stats(&self) -> ArchetypeSystemStats {
let total_archetypes = self.archetypes.len();
let total_entities = self.archetypes.values()
.map(|a| a.entity_count())
.sum();
let average_entities = if total_archetypes > 0 {
total_entities as f64 / total_archetypes as f64
} else {
0.0
};
let cache_hit_rate = if self.stats.total_queries > 0 {
(self.stats.cache_hits as f32 / self.stats.total_queries as f32) * 100.0
} else {
0.0
};
let memory_usage = self.estimate_memory_usage();
ArchetypeSystemStats {
total_archetypes,
total_entities,
average_entities_per_archetype: average_entities,
total_queries: self.stats.total_queries,
cache_hits: self.stats.cache_hits,
cache_hit_rate,
memory_usage_bytes: memory_usage,
}
}
/**
* 清空所有数据
*/
pub fn clear(&mut self) {
self.archetypes.clear();
self.entity_to_archetype.clear();
self.component_to_archetypes.clear();
self.query_cache.clear();
self.stats = ArchetypeSystemStats::default();
}
// ========== 私有方法 ==========
/**
* 创建新原型并建立索引
*/
fn create_archetype(&mut self, archetype: Archetype) {
let archetype_id = archetype.id.clone();
// 为每个组件类型建立索引
for &component_type in &archetype.component_types {
self.component_to_archetypes
.entry(component_type)
.or_insert_with(HashSet::new)
.insert(archetype_id.clone());
}
self.archetypes.insert(archetype_id, archetype);
}
/**
* 从指定原型中移除实体
*/
fn remove_entity_from_archetype(&mut self, entity_id: u32, archetype_id: &str) -> bool {
if let Some(archetype) = self.archetypes.get_mut(archetype_id) {
archetype.remove_entity(entity_id)
} else {
false
}
}
/**
* 获取缓存的查询结果
*/
fn get_cached_result(&self, cache_key: &str) -> Option<ArchetypeQueryResult> {
if let Some(cached) = self.query_cache.get(cache_key) {
let now = current_timestamp();
if now - cached.timestamp < self.cache_timeout_ms {
return Some(ArchetypeQueryResult {
archetypes: cached.result.archetypes.clone(),
total_entities: cached.result.total_entities,
execution_time: cached.result.execution_time,
from_cache: true,
});
}
}
None
}
/**
* 缓存查询结果
*/
fn cache_query_result(&mut self, cache_key: String, result: &ArchetypeQueryResult) {
// 如果缓存已满,清理旧条目
if self.query_cache.len() >= self.max_cache_size {
self.cleanup_old_cache_entries();
}
let cached_result = CachedQueryResult {
result: ArchetypeQueryResult {
archetypes: result.archetypes.clone(),
total_entities: result.total_entities,
execution_time: result.execution_time,
from_cache: false,
},
timestamp: current_timestamp(),
};
self.query_cache.insert(cache_key, cached_result);
}
/**
* 清理过期的缓存条目
*/
fn cleanup_old_cache_entries(&mut self) {
let now = current_timestamp();
let timeout = self.cache_timeout_ms;
self.query_cache.retain(|_, cached| {
now - cached.timestamp < timeout
});
// 如果清理后仍然太多,移除最旧的一半
if self.query_cache.len() >= self.max_cache_size {
let keys_to_remove: Vec<_> = self.query_cache.keys()
.take(self.query_cache.len() / 2)
.cloned()
.collect();
for key in keys_to_remove {
self.query_cache.remove(&key);
}
}
}
/**
* 使查询缓存失效
*/
fn invalidate_query_cache(&mut self) {
self.query_cache.clear();
}
/**
* 估算内存使用量
*/
fn estimate_memory_usage(&self) -> usize {
let archetypes_size = self.archetypes.len() * std::mem::size_of::<Archetype>();
let entity_mapping_size = self.entity_to_archetype.len() * (std::mem::size_of::<u32>() + std::mem::size_of::<String>());
let component_mapping_size = self.component_to_archetypes.len() * std::mem::size_of::<(ComponentType, HashSet<ArchetypeId>)>();
let cache_size = self.query_cache.len() * std::mem::size_of::<CachedQueryResult>();
archetypes_size + entity_mapping_size + component_mapping_size + cache_size
}
}
impl Default for ArchetypeSystem {
fn default() -> Self {
Self::new()
}
}
// ========== 辅助函数 ==========
/**
* 获取当前时间戳(毫秒)
*/
fn current_timestamp() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
/**
* 获取当前时间戳(浮点毫秒,用于精确计时)
*/
fn current_timestamp_f64() -> f64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs_f64() * 1000.0
}
/**
* 计算字符串哈希
*/
fn hash_string(s: &str) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
s.hash(&mut hasher);
hasher.finish()
}
/**
* 计算组件类型哈希
*/
fn hash_component_type(component_type: ComponentType) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
component_type.hash(&mut hasher);
hasher.finish()
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::TypeId;
// 测试用的示例组件
struct TestComponentA;
struct TestComponentB;
struct TestComponentC;
#[test]
fn test_archetype_creation() {
let component_types = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentB>(),
];
let archetype = Archetype::new(component_types.clone());
assert_eq!(archetype.component_types.len(), 2);
assert_eq!(archetype.entity_count(), 0);
assert!(!archetype.id.is_empty());
}
#[test]
fn test_archetype_system_basic() {
let mut system = ArchetypeSystem::new();
let component_types_a = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentB>(),
];
let component_types_b = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentC>(),
];
// 添加实体
system.add_entity(1, component_types_a.clone());
system.add_entity(2, component_types_a.clone());
system.add_entity(3, component_types_b);
let stats = system.get_stats();
assert_eq!(stats.total_archetypes, 2);
assert_eq!(stats.total_entities, 3);
}
#[test]
fn test_archetype_queries() {
let mut system = ArchetypeSystem::new();
let component_types_ab = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentB>(),
];
let component_types_ac = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentC>(),
];
system.add_entity(1, component_types_ab);
system.add_entity(2, component_types_ac);
// 查询包含ComponentA的原型
let result = system.query_all_components(&[TypeId::of::<TestComponentA>()]);
assert_eq!(result.archetypes.len(), 2);
assert_eq!(result.total_entities, 2);
// 查询包含ComponentB的原型
let result = system.query_all_components(&[TypeId::of::<TestComponentB>()]);
assert_eq!(result.archetypes.len(), 1);
assert_eq!(result.total_entities, 1);
}
#[test]
fn test_entity_updates() {
let mut system = ArchetypeSystem::new();
let initial_components = vec![TypeId::of::<TestComponentA>()];
system.add_entity(1, initial_components);
assert_eq!(system.get_stats().total_archetypes, 1);
// 更新实体组件
let new_components = vec![
TypeId::of::<TestComponentA>(),
TypeId::of::<TestComponentB>(),
];
system.update_entity_components(1, new_components);
// 应该创建新的原型
assert_eq!(system.get_stats().total_archetypes, 2);
assert_eq!(system.get_stats().total_entities, 1);
}
#[test]
fn test_cache_functionality() {
let mut system = ArchetypeSystem::new();
system.configure_cache(1000, 10); // 1秒缓存最多10条
let component_types = vec![TypeId::of::<TestComponentA>()];
system.add_entity(1, component_types);
// 第一次查询
let result1 = system.query_all_components(&[TypeId::of::<TestComponentA>()]);
assert!(!result1.from_cache);
// 第二次查询应该从缓存获取
let result2 = system.query_all_components(&[TypeId::of::<TestComponentA>()]);
assert!(result2.from_cache);
let stats = system.get_stats();
assert_eq!(stats.cache_hits, 1);
assert_eq!(stats.total_queries, 2);
}
}

View File

@@ -0,0 +1,376 @@
use rustc_hash::FxHashMap;
use std::any::{Any, TypeId};
use std::sync::atomic::{AtomicU32, Ordering};
/**
* 组件ID生成器
* 全局静态变量为每个组件实例分配唯一ID
*/
static COMPONENT_ID_GENERATOR: AtomicU32 = AtomicU32::new(0);
/**
* 组件注册表
* 管理组件类型的位掩码分配
*/
pub struct ComponentRegistry {
component_types: FxHashMap<TypeId, u32>,
component_names: FxHashMap<String, TypeId>,
component_name_to_id: FxHashMap<String, u32>,
next_bit_index: u32,
max_components: u32,
}
impl ComponentRegistry {
pub fn new() -> Self {
Self {
component_types: FxHashMap::default(),
component_names: FxHashMap::default(),
component_name_to_id: FxHashMap::default(),
next_bit_index: 0,
max_components: 64,
}
}
/**
* 注册组件类型并分配位掩码
* @param type_id 组件类型ID
* @param name 组件名称
* @returns 分配的位索引
*/
pub fn register(&mut self, type_id: TypeId, name: String) -> Result<u32, String> {
if let Some(&existing_index) = self.component_types.get(&type_id) {
return Ok(existing_index);
}
if self.next_bit_index >= self.max_components {
return Err(format!(
"Maximum number of component types ({}) exceeded",
self.max_components
));
}
let bit_index = self.next_bit_index;
self.next_bit_index += 1;
self.component_types.insert(type_id, bit_index);
self.component_names.insert(name.clone(), type_id);
self.component_name_to_id.insert(name, bit_index);
Ok(bit_index)
}
/**
* 获取组件类型的位掩码
* @param type_id 组件类型ID
* @returns 位掩码
*/
pub fn get_bit_mask(&self, type_id: &TypeId) -> Option<u64> {
self.component_types.get(type_id).map(|&bit_index| 1u64 << bit_index)
}
/**
* 获取组件类型的位索引
* @param type_id 组件类型ID
* @returns 位索引
*/
pub fn get_bit_index(&self, type_id: &TypeId) -> Option<u32> {
self.component_types.get(type_id).copied()
}
/**
* 检查组件类型是否已注册
* @param type_id 组件类型ID
* @returns 是否已注册
*/
pub fn is_registered(&self, type_id: &TypeId) -> bool {
self.component_types.contains_key(type_id)
}
/**
* 通过名称获取组件类型ID
* @param name 组件名称
* @returns 组件类型ID
*/
pub fn get_component_id(&self, name: &str) -> Option<u32> {
self.component_name_to_id.get(name).copied()
}
/**
* 创建组件掩码
* @param component_names 组件名称数组
* @returns 组合掩码
*/
pub fn create_component_mask(&self, component_names: &[String]) -> u64 {
let mut mask = 0u64;
for name in component_names {
if let Some(&component_id) = self.component_name_to_id.get(name) {
mask |= 1u64 << component_id;
}
}
mask
}
/**
* 重置注册表
*/
pub fn reset(&mut self) {
self.component_types.clear();
self.component_names.clear();
self.component_name_to_id.clear();
self.next_bit_index = 0;
}
}
/**
* 游戏组件基础trait
*
* ECS架构中的组件Component用于实现具体的游戏功能。
* 组件包含数据和行为,可以被添加到实体上以扩展实体的功能。
*/
pub trait Component: Send + Sync where Self: 'static {
/**
* 获取组件的唯一标识符
* 在整个游戏生命周期中唯一的数字ID
*/
fn id(&self) -> u32;
/**
* 获取组件启用状态
* 组件的实际启用状态取决于自身状态和所属实体的状态
*/
fn enabled(&self) -> bool {
true // 默认启用
}
/**
* 设置组件启用状态
* 当状态改变时会触发相应的生命周期回调
*/
fn set_enabled(&mut self, enabled: bool);
/**
* 获取更新顺序
* 决定组件在更新循环中的执行顺序
*/
fn update_order(&self) -> i32 {
0 // 默认更新顺序
}
/**
* 设置更新顺序
*/
fn set_update_order(&mut self, order: i32);
/**
* 组件添加到实体时的回调
* 当组件被添加到实体时调用,可以在此方法中进行初始化操作
*/
fn on_added_to_entity(&mut self) {}
/**
* 组件从实体移除时的回调
* 当组件从实体中移除时调用,可以在此方法中进行清理操作
*/
fn on_removed_from_entity(&mut self) {}
/**
* 组件启用时的回调
* 当组件被启用时调用
*/
fn on_enabled(&mut self) {}
/**
* 组件禁用时的回调
* 当组件被禁用时调用
*/
fn on_disabled(&mut self) {}
/**
* 实体激活状态改变时的回调
* 当所属实体的激活状态改变时调用
*/
fn on_active_changed(&mut self) {}
/**
* 更新组件
* 每帧调用,用于更新组件的逻辑
* 子类应该重写此方法来实现具体的更新逻辑
*/
fn update(&mut self) {}
// ========== Any trait 方法 ==========
/**
* 获取组件作为Any引用用于类型转换
*/
fn as_any(&self) -> &dyn Any;
/**
* 获取组件作为可变Any引用用于类型转换
*/
fn as_any_mut(&mut self) -> &mut dyn Any;
/**
* 克隆组件到Box中
*/
fn clone_box(&self) -> Box<dyn Component>;
/**
* 获取组件的TypeId
*/
fn type_id(&self) -> TypeId {
TypeId::of::<Self>()
}
/**
* 获取组件类型名称(用于调试)
*/
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
}
/**
* 为Box<dyn Component>实现Clone
*/
impl Clone for Box<dyn Component> {
fn clone(&self) -> Box<dyn Component> {
self.clone_box()
}
}
/**
* 基础组件实现
* 提供默认的组件行为,具体组件可以继承此结构体
*/
#[derive(Debug, Clone)]
pub struct BaseComponent {
/// 组件唯一标识符
id: u32,
/// 组件启用状态
enabled: bool,
/// 更新顺序
update_order: i32,
}
impl BaseComponent {
/**
* 创建新的基础组件
*/
pub fn new() -> Self {
Self {
id: COMPONENT_ID_GENERATOR.fetch_add(1, Ordering::SeqCst),
enabled: true,
update_order: 0,
}
}
/**
* 生成下一个组件ID
*/
pub fn next_component_id() -> u32 {
COMPONENT_ID_GENERATOR.fetch_add(1, Ordering::SeqCst)
}
/**
* 设置组件ID
*/
pub fn set_id(&mut self, id: u32) {
self.id = id;
}
}
impl Default for BaseComponent {
fn default() -> Self {
Self::new()
}
}
impl Component for BaseComponent {
fn id(&self) -> u32 {
self.id
}
fn enabled(&self) -> bool {
self.enabled
}
fn set_enabled(&mut self, enabled: bool) {
if self.enabled != enabled {
self.enabled = enabled;
if enabled {
self.on_enabled();
} else {
self.on_disabled();
}
}
}
fn update_order(&self) -> i32 {
self.update_order
}
fn set_update_order(&mut self, order: i32) {
self.update_order = order;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn clone_box(&self) -> Box<dyn Component> {
Box::new(BaseComponent {
id: BaseComponent::next_component_id(), // 新的克隆应该有新的ID
enabled: self.enabled,
update_order: self.update_order,
})
}
}
/**
* 组件宏,用于简化自定义组件的实现
*/
#[macro_export]
macro_rules! impl_component {
($component_type:ty) => {
impl Component for $component_type {
fn id(&self) -> u32 {
self.base.id()
}
fn enabled(&self) -> bool {
self.base.enabled()
}
fn set_enabled(&mut self, enabled: bool) {
self.base.set_enabled(enabled)
}
fn update_order(&self) -> i32 {
self.base.update_order()
}
fn set_update_order(&mut self, order: i32) {
self.base.set_update_order(order)
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn clone_box(&self) -> Box<dyn Component> {
Box::new(self.clone())
}
}
};
}

View File

@@ -0,0 +1,352 @@
use std::marker::PhantomData;
use crate::core::{Component, BaseComponent};
/**
* 组件构建器
* 提供流式API创建和配置组件
*/
pub struct ComponentBuilder<T: Component> {
component: T,
_phantom: PhantomData<T>,
}
impl<T: Component> ComponentBuilder<T> {
/**
* 创建组件构建器
*/
pub fn new(component: T) -> Self {
Self {
component,
_phantom: PhantomData,
}
}
/**
* 设置组件启用状态
*/
pub fn enabled(mut self, enabled: bool) -> Self {
self.component.set_enabled(enabled);
self
}
/**
* 条件性设置启用状态
*/
pub fn enabled_if(mut self, condition: bool, enabled: bool) -> Self {
if condition {
self.component.set_enabled(enabled);
}
self
}
/**
* 使用配置函数设置组件
*/
pub fn configure<F>(mut self, configurator: F) -> Self
where
F: FnOnce(&mut T),
{
configurator(&mut self.component);
self
}
/**
* 条件性配置组件
*/
pub fn configure_if<F>(mut self, condition: bool, configurator: F) -> Self
where
F: FnOnce(&mut T),
{
if condition {
configurator(&mut self.component);
}
self
}
/**
* 构建并返回组件
*/
pub fn build(self) -> T {
self.component
}
/**
* 验证组件配置并构建
*/
pub fn validate_and_build<F>(self, validator: F) -> Result<T, String>
where
F: FnOnce(&T) -> Result<(), String>,
{
match validator(&self.component) {
Ok(()) => Ok(self.component),
Err(error) => Err(error),
}
}
}
/**
* 基础组件构建器
* 为BaseComponent提供特化的构建器实现
*/
pub struct BaseComponentBuilder {
component: BaseComponent,
}
impl BaseComponentBuilder {
/**
* 创建基础组件构建器
*/
pub fn new() -> Self {
Self {
component: BaseComponent::new(),
}
}
/**
* 设置组件启用状态
*/
pub fn enabled(mut self, enabled: bool) -> Self {
self.component.set_enabled(enabled);
self
}
/**
* 设置组件ID
*/
pub fn with_id(mut self, id: u32) -> Self {
self.component.set_id(id);
self
}
/**
* 条件性设置启用状态
*/
pub fn enabled_if(mut self, condition: bool, enabled: bool) -> Self {
if condition {
self.component.set_enabled(enabled);
}
self
}
/**
* 使用配置函数设置组件
*/
pub fn configure<F>(mut self, configurator: F) -> Self
where
F: FnOnce(&mut BaseComponent),
{
configurator(&mut self.component);
self
}
/**
* 构建并返回组件
*/
pub fn build(self) -> BaseComponent {
self.component
}
}
/**
* 组件构建器工厂
* 提供创建各种组件构建器的便捷方法
*/
pub struct ComponentBuilderFactory;
impl ComponentBuilderFactory {
/**
* 创建基础组件构建器
*/
pub fn base_component() -> BaseComponentBuilder {
BaseComponentBuilder::new()
}
/**
* 创建通用组件构建器
*/
pub fn component<T: Component>(component: T) -> ComponentBuilder<T> {
ComponentBuilder::new(component)
}
/**
* 创建启用的基础组件
*/
pub fn enabled_base_component() -> BaseComponentBuilder {
BaseComponentBuilder::new().enabled(true)
}
/**
* 创建禁用的基础组件
*/
pub fn disabled_base_component() -> BaseComponentBuilder {
BaseComponentBuilder::new().enabled(false)
}
}
/**
* 组件构建器统计信息
*/
#[derive(Debug, Clone)]
pub struct ComponentBuilderStats {
pub total_components_built: u64,
pub base_components_built: u64,
pub custom_components_built: u64,
pub validation_failures: u64,
}
impl ComponentBuilderStats {
pub fn new() -> Self {
Self {
total_components_built: 0,
base_components_built: 0,
custom_components_built: 0,
validation_failures: 0,
}
}
/**
* 重置统计信息
*/
pub fn reset(&mut self) {
self.total_components_built = 0;
self.base_components_built = 0;
self.custom_components_built = 0;
self.validation_failures = 0;
}
/**
* 记录基础组件构建
*/
pub fn record_base_component_built(&mut self) {
self.total_components_built += 1;
self.base_components_built += 1;
}
/**
* 记录自定义组件构建
*/
pub fn record_custom_component_built(&mut self) {
self.total_components_built += 1;
self.custom_components_built += 1;
}
/**
* 记录验证失败
*/
pub fn record_validation_failure(&mut self) {
self.validation_failures += 1;
}
/**
* 获取构建成功率
*/
pub fn success_rate(&self) -> f64 {
if self.total_components_built + self.validation_failures == 0 {
return 1.0;
}
self.total_components_built as f64 /
(self.total_components_built + self.validation_failures) as f64
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_base_component_builder() {
let component = BaseComponentBuilder::new()
.enabled(true)
.with_id(123)
.build();
assert!(component.enabled());
assert_eq!(component.id(), 123);
}
#[test]
fn test_base_component_builder_conditional() {
let component = BaseComponentBuilder::new()
.enabled_if(true, true)
.enabled_if(false, false)
.build();
assert!(component.enabled());
}
#[test]
fn test_base_component_builder_configure() {
let component = BaseComponentBuilder::new()
.configure(|comp| {
comp.set_enabled(true);
comp.set_id(456);
})
.build();
assert!(component.enabled());
assert_eq!(component.id(), 456);
}
#[test]
fn test_component_builder_factory() {
let base_comp = ComponentBuilderFactory::base_component().build();
assert!(!base_comp.enabled()); // 默认为禁用
let enabled_comp = ComponentBuilderFactory::enabled_base_component().build();
assert!(enabled_comp.enabled());
let disabled_comp = ComponentBuilderFactory::disabled_base_component().build();
assert!(!disabled_comp.enabled());
}
#[test]
fn test_component_builder_validation() {
let component = BaseComponent::new();
let builder = ComponentBuilder::new(component);
// 验证成功
let result = builder.validate_and_build(|_| Ok(()));
assert!(result.is_ok());
// 验证失败
let component2 = BaseComponent::new();
let builder2 = ComponentBuilder::new(component2);
let result2 = builder2.validate_and_build(|_| Err("Invalid component".to_string()));
assert!(result2.is_err());
assert_eq!(result2.unwrap_err(), "Invalid component");
}
#[test]
fn test_component_builder_stats() {
let mut stats = ComponentBuilderStats::new();
stats.record_base_component_built();
stats.record_custom_component_built();
stats.record_validation_failure();
assert_eq!(stats.total_components_built, 2);
assert_eq!(stats.base_components_built, 1);
assert_eq!(stats.custom_components_built, 1);
assert_eq!(stats.validation_failures, 1);
assert!((stats.success_rate() - 0.6666666666666666).abs() < 0.0001);
}
#[test]
fn test_component_builder_stats_reset() {
let mut stats = ComponentBuilderStats::new();
stats.record_base_component_built();
stats.reset();
assert_eq!(stats.total_components_built, 0);
assert_eq!(stats.base_components_built, 0);
assert_eq!(stats.custom_components_built, 0);
assert_eq!(stats.validation_failures, 0);
}
#[test]
fn test_component_builder_stats_success_rate_empty() {
let stats = ComponentBuilderStats::new();
assert_eq!(stats.success_rate(), 1.0);
}
}

View File

@@ -0,0 +1,638 @@
use crate::core::component::Component;
use rustc_hash::FxHashMap;
use std::any::TypeId;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
/// 将TypeId转换为u64的帮助函数
fn type_id_to_u64(type_id: TypeId) -> u64 {
let mut hasher = DefaultHasher::new();
type_id.hash(&mut hasher);
hasher.finish()
}
/**
* 实体比较器
*
* 用于比较两个实体的优先级首先按更新顺序比较然后按ID比较
*/
pub struct EntityComparer;
impl EntityComparer {
/**
* 比较两个实体
*
* @param self_entity - 第一个实体
* @param other_entity - 第二个实体
* @returns 比较结果负数表示self优先级更高正数表示other优先级更高0表示相等
*/
pub fn compare(self_entity: &Entity, other_entity: &Entity) -> i32 {
let mut compare = self_entity.update_order - other_entity.update_order;
if compare == 0 {
compare = self_entity.id as i32 - other_entity.id as i32;
}
compare
}
}
/**
* 游戏实体类
*
* ECS架构中的实体Entity作为组件的容器。
* 实体本身不包含游戏逻辑,所有功能都通过组件来实现。
* 支持父子关系,可以构建实体层次结构。
*/
#[derive(Clone)]
pub struct Entity {
/// 实体名称,用于标识和调试的友好名称
pub name: String,
/// 实体唯一标识符,在场景中唯一的数字标识符
pub id: u32,
/// 更新间隔,控制实体更新的频率,值越大更新越不频繁
pub update_interval: u32,
/// 私有字段通过getter/setter访问
active: bool,
enabled: bool,
is_destroyed: bool,
tag: u32,
update_order: i32,
/// 父实体ID
parent_id: Option<u32>,
/// 子实体ID集合
children_ids: Vec<u32>,
/// 组件位掩码,用于快速查询实体拥有的组件类型
component_mask: u64,
/// 组件实例存储 (TypeId -> 组件数据)
components: FxHashMap<TypeId, Box<dyn Component>>,
/// 组件类型到索引的映射,用于快速定位组件在数组中的位置
component_type_to_index: FxHashMap<TypeId, usize>,
/// 组件列表(用于保持插入顺序和索引访问)
component_list: Vec<Option<Box<dyn Component>>>,
}
impl Entity {
/**
* 构造函数
*/
pub fn new(id: u32) -> Self {
Self {
name: String::new(),
id,
update_interval: 1,
active: true,
enabled: true,
is_destroyed: false,
tag: 0,
update_order: 0,
parent_id: None,
children_ids: Vec::new(),
component_mask: 0,
components: FxHashMap::default(),
component_type_to_index: FxHashMap::default(),
component_list: Vec::new(),
}
}
/**
* 构造函数(带名称)
*/
pub fn new_with_name(name: String, id: u32) -> Self {
Self {
name,
id,
update_interval: 1,
active: true,
enabled: true,
is_destroyed: false,
tag: 0,
update_order: 0,
parent_id: None,
children_ids: Vec::new(),
component_mask: 0,
components: FxHashMap::default(),
component_type_to_index: FxHashMap::default(),
component_list: Vec::new(),
}
}
// ========== 属性访问器 ==========
/**
* 获取实体ID
*/
pub fn id(&self) -> u32 {
self.id
}
/**
* 设置实体ID
*/
pub fn set_id(&mut self, id: u32) {
self.id = id;
}
/**
* 获取实体名称
*/
pub fn name(&self) -> Option<String> {
if self.name.is_empty() {
None
} else {
Some(self.name.clone())
}
}
/**
* 设置实体名称
*/
pub fn set_name(&mut self, name: String) {
self.name = name;
}
/**
* 获取标签集合(暂时返回单个标签作为集合)
*/
pub fn tags(&self) -> std::collections::HashSet<u32> {
let mut tags = std::collections::HashSet::new();
if self.tag != 0 {
tags.insert(self.tag);
}
tags
}
/**
* 检查是否有指定标签
*/
pub fn has_tag(&self, tag: u32) -> bool {
self.tag == tag
}
/**
* 添加标签
*/
pub fn add_tag(&mut self, tag: u32) {
self.tag = tag; // 简化版本,只支持单个标签
}
/**
* 移除标签
*/
pub fn remove_tag(&mut self, tag: u32) {
if self.tag == tag {
self.tag = 0;
}
}
pub fn active(&self) -> bool {
self.active
}
pub fn set_active(&mut self, value: bool) {
if self.active != value {
self.active = value;
self.on_active_changed();
}
}
pub fn enabled(&self) -> bool {
self.enabled
}
pub fn set_enabled(&mut self, value: bool) {
self.enabled = value;
}
pub fn tag(&self) -> u32 {
self.tag
}
pub fn set_tag(&mut self, value: u32) {
self.tag = value;
}
pub fn update_order(&self) -> i32 {
self.update_order
}
pub fn set_update_order(&mut self, value: i32) {
self.update_order = value;
}
pub fn is_destroyed(&self) -> bool {
self.is_destroyed
}
pub fn get_parent_id(&self) -> Option<u32> {
self.parent_id
}
pub fn child_count(&self) -> usize {
self.children_ids.len()
}
pub fn get_component_mask(&self) -> u64 {
self.component_mask
}
pub fn get_children_ids(&self) -> Vec<u32> {
self.children_ids.clone()
}
// ========== 内部访问方法 ==========
/**
* 获取子实体ID的切片引用内部使用
*/
pub fn children_ids(&self) -> &[u32] {
&self.children_ids
}
/**
* 获取父实体ID内部使用
*/
pub fn parent_id(&self) -> Option<u32> {
self.parent_id
}
/**
* 设置组件位掩码(内部使用)
*/
pub fn set_component_mask(&mut self, mask: u64) {
self.component_mask = mask;
}
/**
* 获取调试信息字符串
*/
pub fn get_debug_info(&self) -> String {
format!(
"{{\"name\":\"{}\",\"id\":{},\"enabled\":{},\"active\":{},\"destroyed\":{},\"component_count\":{},\"tag\":{},\"update_order\":{},\"child_count\":{}}}",
self.name,
self.id,
self.enabled,
self.active,
self.is_destroyed,
self.components.len(),
self.tag,
self.update_order,
self.children_ids.len()
)
}
/**
* 获取调试信息结构体(内部使用)
*/
pub fn get_debug_info_struct(&self) -> EntityDebugInfo {
EntityDebugInfo {
name: self.name.clone(),
id: self.id,
enabled: self.enabled,
active: self.active,
destroyed: self.is_destroyed,
component_count: self.components.len(),
component_mask: format!("{:b}", self.component_mask),
parent_id: self.parent_id,
child_count: self.children_ids.len(),
child_ids: self.children_ids.clone(),
tag: self.tag,
update_order: self.update_order,
index_mapping_size: self.component_type_to_index.len(),
}
}
// ========== 组件管理 ==========
/**
* 内部添加组件方法(不进行重复检查,用于初始化)
*/
fn add_component_internal<T: Component + 'static>(&mut self, component: T) -> &T {
let type_id = TypeId::of::<T>();
let boxed_component = Box::new(component);
// 添加到组件列表并建立索引映射
let index = self.component_list.len();
self.component_list.push(Some(boxed_component.clone_box()));
self.component_type_to_index.insert(type_id, index);
// 添加到类型映射
self.components.insert(type_id, boxed_component);
// 这里应该更新位掩码但需要ComponentRegistry
// 暂时使用简单的类型ID哈希作为掩码
self.component_mask |= 1u64.wrapping_shl(type_id_to_u64(type_id) as u32 % 64);
// 返回引用(这里简化处理)
self.components.get(&type_id).unwrap().as_any().downcast_ref::<T>().unwrap()
}
/**
* 添加组件到实体
*/
pub fn add_component<T: Component + 'static>(&mut self, component: T) -> Result<&T, String> {
let type_id = TypeId::of::<T>();
// 检查是否已有此类型的组件
if self.has_component::<T>() {
return Err(format!("Entity {} already has component of type {:?}", self.name, type_id));
}
// 使用内部方法添加组件
Ok(self.add_component_internal(component))
}
/**
* 获取指定类型的组件
*/
pub fn get_component<T: Component + 'static>(&self) -> Option<&T> {
let type_id = TypeId::of::<T>();
// 首先检查位掩码,快速排除(简化版本)
let type_mask = 1u64.wrapping_shl(type_id_to_u64(type_id) as u32 % 64);
if (self.component_mask & type_mask) == 0 {
return None;
}
// 从类型映射获取
self.components.get(&type_id).and_then(|component| {
component.as_any().downcast_ref::<T>()
})
}
/**
* 获取指定类型的可变组件
*/
pub fn get_component_mut<T: Component + 'static>(&mut self) -> Option<&mut T> {
let type_id = TypeId::of::<T>();
// 首先检查位掩码,快速排除
let type_mask = 1u64.wrapping_shl(type_id_to_u64(type_id) as u32 % 64);
if (self.component_mask & type_mask) == 0 {
return None;
}
// 从类型映射获取可变引用
self.components.get_mut(&type_id).and_then(|component| {
component.as_any_mut().downcast_mut::<T>()
})
}
/**
* 检查实体是否有指定类型的组件
*/
pub fn has_component<T: Component + 'static>(&self) -> bool {
let type_id = TypeId::of::<T>();
let type_mask = 1u64.wrapping_shl(type_id_to_u64(type_id) as u32 % 64);
(self.component_mask & type_mask) != 0
}
/**
* 获取或创建指定类型的组件
*/
pub fn get_or_create_component<T: Component + Default + 'static>(&mut self) -> &T {
if self.has_component::<T>() {
self.get_component::<T>().unwrap()
} else {
let component = T::default();
self.add_component_internal(component)
}
}
/**
* 移除指定类型的组件
*/
pub fn remove_component<T: Component + 'static>(&mut self) -> Option<Box<dyn Component>> {
let type_id = TypeId::of::<T>();
if let Some(component) = self.components.remove(&type_id) {
// 更新位掩码
let type_mask = 1u64.wrapping_shl(type_id_to_u64(type_id) as u32 % 64);
self.component_mask &= !type_mask;
// 从索引映射中移除并重建索引
if let Some(index) = self.component_type_to_index.remove(&type_id) {
if index < self.component_list.len() {
self.component_list[index] = None;
}
self.rebuild_component_index();
}
Some(component)
} else {
None
}
}
/**
* 移除所有组件
*/
pub fn remove_all_components(&mut self) {
self.component_type_to_index.clear();
self.component_mask = 0;
self.components.clear();
self.component_list.clear();
}
/**
* 获取组件数量
*/
pub fn component_count(&self) -> usize {
self.components.len()
}
/**
* 重建组件索引映射
*/
fn rebuild_component_index(&mut self) {
self.component_type_to_index.clear();
let mut new_list = Vec::new();
for (_i, component_opt) in self.component_list.iter().enumerate() {
if let Some(component) = component_opt {
let type_id = component.type_id();
self.component_type_to_index.insert(type_id, new_list.len());
new_list.push(Some(component.clone_box()));
}
}
self.component_list = new_list;
}
// ========== 层次结构管理 ==========
/**
* 添加子实体ID
*/
pub fn add_child_id(&mut self, child_id: u32) -> Result<(), String> {
if child_id == self.id {
return Err("Entity cannot be its own child".to_string());
}
if self.children_ids.contains(&child_id) {
return Ok(()); // 已经是子实体
}
self.children_ids.push(child_id);
Ok(())
}
/**
* 移除子实体ID
*/
pub fn remove_child_id(&mut self, child_id: u32) -> bool {
if let Some(pos) = self.children_ids.iter().position(|&id| id == child_id) {
self.children_ids.remove(pos);
true
} else {
false
}
}
/**
* 设置父实体ID
*/
pub fn set_parent_id(&mut self, parent_id: Option<u32>) {
self.parent_id = parent_id;
}
/**
* 移除所有子实体ID
*/
pub fn remove_all_children_ids(&mut self) {
self.children_ids.clear();
}
// ========== 生命周期方法 ==========
/**
* 激活状态改变时的回调
*/
fn on_active_changed(&mut self) {
// 通知所有组件激活状态改变
for component in self.components.values_mut() {
component.on_active_changed();
}
}
/**
* 更新实体
*/
pub fn update(&mut self) {
if !self.active || self.is_destroyed {
return;
}
// 更新所有组件
for component in self.components.values_mut() {
if component.enabled() {
component.update();
}
}
}
/**
* 销毁实体
*/
pub fn destroy(&mut self) {
if self.is_destroyed {
return;
}
self.is_destroyed = true;
// 移除所有组件
self.remove_all_components();
// 清空子实体ID实际的子实体销毁由EntityManager处理
self.children_ids.clear();
// 清空父实体引用
self.parent_id = None;
}
/**
* 比较实体
*/
pub fn compare_to(&self, other: &Entity) -> i32 {
EntityComparer::compare(self, other)
}
/**
* 获取实体的字符串表示
*/
pub fn to_string(&self) -> String {
format!("Entity[{}:{}]", self.name, self.id)
}
/**
* 获取实体的调试信息结构体
*/
pub fn get_debug_info_detailed(&self) -> EntityDebugInfo {
EntityDebugInfo {
name: self.name.clone(),
id: self.id,
enabled: self.enabled,
active: self.active,
destroyed: self.is_destroyed,
component_count: self.components.len(),
component_mask: format!("{:b}", self.component_mask),
parent_id: self.parent_id,
child_count: self.children_ids.len(),
child_ids: self.children_ids.clone(),
tag: self.tag,
update_order: self.update_order,
index_mapping_size: self.component_type_to_index.len(),
}
}
}
/**
* 实体调试信息
*/
#[derive(serde::Serialize, serde::Deserialize)]
pub struct EntityDebugInfo {
pub name: String,
pub id: u32,
pub enabled: bool,
pub active: bool,
pub destroyed: bool,
pub component_count: usize,
pub component_mask: String,
pub parent_id: Option<u32>,
pub child_count: usize,
pub child_ids: Vec<u32>,
pub tag: u32,
pub update_order: i32,
pub index_mapping_size: usize,
}
impl std::fmt::Display for Entity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Entity[{}:{}]", self.name, self.id)
}
}
impl std::fmt::Debug for Entity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Entity")
.field("name", &self.name)
.field("id", &self.id)
.field("active", &self.active)
.field("enabled", &self.enabled)
.field("is_destroyed", &self.is_destroyed)
.field("tag", &self.tag)
.field("update_order", &self.update_order)
.field("parent_id", &self.parent_id)
.field("children_count", &self.children_ids.len())
.field("component_count", &self.components.len())
.finish()
}
}

View File

@@ -0,0 +1,630 @@
use std::collections::HashMap;
use crate::core::{Entity, ComponentRegistry};
/**
* 实体批量操作器
* 提供对多个实体的批量操作功能
*/
pub struct EntityBatchOperator {
entities: Vec<Entity>,
component_registry: ComponentRegistry,
}
impl EntityBatchOperator {
/**
* 创建批量操作器
*/
pub fn new(entities: Vec<Entity>) -> Self {
Self {
entities,
component_registry: ComponentRegistry::new(),
}
}
/**
* 从实体ID创建批量操作器
*/
pub fn from_ids(entity_ids: Vec<u32>) -> Self {
let entities: Vec<Entity> = entity_ids
.into_iter()
.map(|id| {
let mut entity = Entity::new(id);
entity.set_id(id);
entity
})
.collect();
Self::new(entities)
}
/**
* 批量设置活跃状态
*/
pub fn set_enabled(&mut self, enabled: bool) -> &mut Self {
for entity in &mut self.entities {
entity.set_enabled(enabled);
}
self
}
/**
* 批量设置名称
*/
pub fn set_name(&mut self, name: &str) -> &mut Self {
for entity in &mut self.entities {
entity.set_name(name.to_string());
}
self
}
/**
* 批量设置标签
*/
pub fn set_tag(&mut self, tag: u32) -> &mut Self {
for entity in &mut self.entities {
entity.set_tag(tag);
}
self
}
/**
* 批量添加标签
*/
pub fn add_tag(&mut self, tag: u32) -> &mut Self {
for entity in &mut self.entities {
entity.add_tag(tag);
}
self
}
/**
* 批量移除标签
*/
pub fn remove_tag(&mut self, tag: u32) -> &mut Self {
for entity in &mut self.entities {
entity.remove_tag(tag);
}
self
}
/**
* 批量执行操作
*/
pub fn for_each<F>(&mut self, mut operation: F) -> &mut Self
where
F: FnMut(&mut Entity, usize),
{
for (index, entity) in self.entities.iter_mut().enumerate() {
operation(entity, index);
}
self
}
/**
* 批量执行只读操作
*/
pub fn for_each_readonly<F>(&self, mut operation: F) -> &Self
where
F: FnMut(&Entity, usize),
{
for (index, entity) in self.entities.iter().enumerate() {
operation(entity, index);
}
self
}
/**
* 过滤实体
*/
pub fn filter<F>(self, predicate: F) -> Self
where
F: Fn(&Entity) -> bool,
{
let filtered_entities: Vec<Entity> = self.entities
.into_iter()
.filter(|entity| predicate(entity))
.collect();
Self::new(filtered_entities)
}
/**
* 按条件分组
*/
pub fn group_by<F, K>(self, key_fn: F) -> HashMap<K, EntityBatchOperator>
where
F: Fn(&Entity) -> K,
K: Eq + std::hash::Hash,
{
let mut groups: HashMap<K, Vec<Entity>> = HashMap::new();
for entity in self.entities {
let key = key_fn(&entity);
groups.entry(key).or_insert_with(Vec::new).push(entity);
}
groups.into_iter()
.map(|(key, entities)| (key, EntityBatchOperator::new(entities)))
.collect()
}
/**
* 获取实体数量
*/
pub fn count(&self) -> usize {
self.entities.len()
}
/**
* 检查是否为空
*/
pub fn is_empty(&self) -> bool {
self.entities.is_empty()
}
/**
* 获取第一个实体的只读引用
*/
pub fn first(&self) -> Option<&Entity> {
self.entities.first()
}
/**
* 获取第一个实体的可变引用
*/
pub fn first_mut(&mut self) -> Option<&mut Entity> {
self.entities.first_mut()
}
/**
* 获取最后一个实体的只读引用
*/
pub fn last(&self) -> Option<&Entity> {
self.entities.last()
}
/**
* 获取最后一个实体的可变引用
*/
pub fn last_mut(&mut self) -> Option<&mut Entity> {
self.entities.last_mut()
}
/**
* 获取指定索引的实体
*/
pub fn get(&self, index: usize) -> Option<&Entity> {
self.entities.get(index)
}
/**
* 获取指定索引的可变实体
*/
pub fn get_mut(&mut self, index: usize) -> Option<&mut Entity> {
self.entities.get_mut(index)
}
/**
* 清空所有实体
*/
pub fn clear(&mut self) -> &mut Self {
self.entities.clear();
self
}
/**
* 添加实体
*/
pub fn add_entity(&mut self, entity: Entity) -> &mut Self {
self.entities.push(entity);
self
}
/**
* 添加多个实体
*/
pub fn add_entities(&mut self, mut entities: Vec<Entity>) -> &mut Self {
self.entities.append(&mut entities);
self
}
/**
* 移除指定索引的实体
*/
pub fn remove_at(&mut self, index: usize) -> Option<Entity> {
if index < self.entities.len() {
Some(self.entities.remove(index))
} else {
None
}
}
/**
* 移除满足条件的实体
*/
pub fn remove_if<F>(&mut self, predicate: F) -> &mut Self
where
F: Fn(&Entity) -> bool,
{
self.entities.retain(|entity| !predicate(entity));
self
}
/**
* 获取所有实体ID
*/
pub fn get_entity_ids(&self) -> Vec<u32> {
self.entities.iter().map(|entity| entity.id()).collect()
}
/**
* 检查是否包含指定ID的实体
*/
pub fn contains_entity(&self, entity_id: u32) -> bool {
self.entities.iter().any(|entity| entity.id() == entity_id)
}
/**
* 按ID查找实体
*/
pub fn find_by_id(&self, entity_id: u32) -> Option<&Entity> {
self.entities.iter().find(|entity| entity.id() == entity_id)
}
/**
* 按ID查找可变实体
*/
pub fn find_by_id_mut(&mut self, entity_id: u32) -> Option<&mut Entity> {
self.entities.iter_mut().find(|entity| entity.id() == entity_id)
}
/**
* 按名称查找实体
*/
pub fn find_by_name(&self, name: &str) -> Vec<&Entity> {
self.entities
.iter()
.filter(|entity| entity.name().as_deref() == Some(name))
.collect()
}
/**
* 按标签查找实体
*/
pub fn find_by_tag(&self, tag: u32) -> Vec<&Entity> {
self.entities
.iter()
.filter(|entity| entity.has_tag(tag))
.collect()
}
/**
* 获取启用的实体
*/
pub fn get_enabled(&self) -> Vec<&Entity> {
self.entities
.iter()
.filter(|entity| entity.enabled())
.collect()
}
/**
* 获取禁用的实体
*/
pub fn get_disabled(&self) -> Vec<&Entity> {
self.entities
.iter()
.filter(|entity| !entity.enabled())
.collect()
}
/**
* 排序实体
*/
pub fn sort_by<F>(&mut self, compare: F) -> &mut Self
where
F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
{
self.entities.sort_by(compare);
self
}
/**
* 按ID排序
*/
pub fn sort_by_id(&mut self) -> &mut Self {
self.entities.sort_by(|a, b| a.id().cmp(&b.id()));
self
}
/**
* 按名称排序
*/
pub fn sort_by_name(&mut self) -> &mut Self {
self.entities.sort_by(|a, b| a.name().cmp(&b.name()));
self
}
/**
* 转换为实体数组
*/
pub fn to_vec(self) -> Vec<Entity> {
self.entities
}
/**
* 转换为实体ID数组
*/
pub fn to_id_vec(&self) -> Vec<u32> {
self.get_entity_ids()
}
/**
* 克隆实体数组
*/
pub fn clone_entities(&self) -> Vec<Entity> {
self.entities.clone()
}
}
/**
* 批量操作统计信息
*/
#[derive(Debug, Clone)]
pub struct BatchOperatorStats {
pub total_operations: u64,
pub entities_processed: u64,
pub filters_applied: u64,
pub groups_created: u64,
pub sorts_performed: u64,
}
impl BatchOperatorStats {
pub fn new() -> Self {
Self {
total_operations: 0,
entities_processed: 0,
filters_applied: 0,
groups_created: 0,
sorts_performed: 0,
}
}
/**
* 重置统计信息
*/
pub fn reset(&mut self) {
self.total_operations = 0;
self.entities_processed = 0;
self.filters_applied = 0;
self.groups_created = 0;
self.sorts_performed = 0;
}
/**
* 记录操作
*/
pub fn record_operation(&mut self, entities_count: usize) {
self.total_operations += 1;
self.entities_processed += entities_count as u64;
}
/**
* 记录过滤操作
*/
pub fn record_filter(&mut self) {
self.filters_applied += 1;
}
/**
* 记录分组操作
*/
pub fn record_group(&mut self) {
self.groups_created += 1;
}
/**
* 记录排序操作
*/
pub fn record_sort(&mut self) {
self.sorts_performed += 1;
}
/**
* 获取平均处理实体数
*/
pub fn average_entities_per_operation(&self) -> f64 {
if self.total_operations == 0 {
0.0
} else {
self.entities_processed as f64 / self.total_operations as f64
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create_test_entities() -> Vec<Entity> {
vec![
{
let mut e = Entity::new(1);
e.set_name("Entity1".to_string());
e.set_tag(100);
e
},
{
let mut e = Entity::new(2);
e.set_name("Entity2".to_string());
e.set_tag(200);
e.set_enabled(false);
e
},
{
let mut e = Entity::new(3);
e.set_name("Entity3".to_string());
e.set_tag(100);
e
},
]
}
#[test]
fn test_batch_operator_creation() {
let entities = create_test_entities();
let operator = EntityBatchOperator::new(entities);
assert_eq!(operator.count(), 3);
assert!(!operator.is_empty());
}
#[test]
fn test_batch_operator_from_ids() {
let ids = vec![1, 2, 3];
let operator = EntityBatchOperator::from_ids(ids);
assert_eq!(operator.count(), 3);
assert_eq!(operator.get_entity_ids(), vec![1, 2, 3]);
}
#[test]
fn test_batch_set_enabled() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
operator.set_enabled(false);
assert_eq!(operator.get_enabled().len(), 0);
assert_eq!(operator.get_disabled().len(), 3);
}
#[test]
fn test_batch_set_name() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
operator.set_name("NewName");
for entity in operator.entities.iter() {
assert_eq!(entity.name().as_deref(), Some("NewName"));
}
}
#[test]
fn test_batch_tags() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
operator.add_tag(999);
for entity in operator.entities.iter() {
assert!(entity.has_tag(999));
}
operator.remove_tag(999);
for entity in operator.entities.iter() {
assert!(!entity.has_tag(999));
}
}
#[test]
fn test_batch_for_each() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
let mut count = 0;
operator.for_each(|_, index| {
count += index + 1;
});
assert_eq!(count, 6); // 1 + 2 + 3
}
#[test]
fn test_batch_filter() {
let entities = create_test_entities();
let operator = EntityBatchOperator::new(entities);
let filtered = operator.filter(|entity| entity.has_tag(100));
assert_eq!(filtered.count(), 2);
}
#[test]
fn test_batch_group_by() {
let entities = create_test_entities();
let operator = EntityBatchOperator::new(entities);
let groups = operator.group_by(|entity| entity.enabled());
assert_eq!(groups.len(), 2);
assert!(groups.contains_key(&true));
assert!(groups.contains_key(&false));
}
#[test]
fn test_batch_first_last() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
assert_eq!(operator.first().unwrap().id(), 1);
assert_eq!(operator.last().unwrap().id(), 3);
operator.first_mut().unwrap().set_name("Modified".to_string());
assert_eq!(operator.first().unwrap().name().as_deref(), Some("Modified"));
}
#[test]
fn test_batch_find_operations() {
let entities = create_test_entities();
let operator = EntityBatchOperator::new(entities);
assert!(operator.find_by_id(2).is_some());
assert!(operator.find_by_id(999).is_none());
let found_by_name = operator.find_by_name("Entity2");
assert_eq!(found_by_name.len(), 1);
let found_by_tag = operator.find_by_tag(100);
assert_eq!(found_by_tag.len(), 2);
}
#[test]
fn test_batch_sort() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
// 按ID降序排序
operator.sort_by(|a, b| b.id().cmp(&a.id()));
assert_eq!(operator.get(0).unwrap().id(), 3);
assert_eq!(operator.get(2).unwrap().id(), 1);
// 按ID升序排序
operator.sort_by_id();
assert_eq!(operator.get(0).unwrap().id(), 1);
assert_eq!(operator.get(2).unwrap().id(), 3);
}
#[test]
fn test_batch_stats() {
let mut stats = BatchOperatorStats::new();
stats.record_operation(5);
stats.record_filter();
stats.record_group();
stats.record_sort();
assert_eq!(stats.total_operations, 1);
assert_eq!(stats.entities_processed, 5);
assert_eq!(stats.filters_applied, 1);
assert_eq!(stats.groups_created, 1);
assert_eq!(stats.sorts_performed, 1);
assert_eq!(stats.average_entities_per_operation(), 5.0);
}
#[test]
fn test_batch_remove_operations() {
let entities = create_test_entities();
let mut operator = EntityBatchOperator::new(entities);
let removed = operator.remove_at(1);
assert!(removed.is_some());
assert_eq!(removed.unwrap().id(), 2);
assert_eq!(operator.count(), 2);
operator.remove_if(|entity| entity.has_tag(100));
assert_eq!(operator.count(), 0);
}
}

View File

@@ -0,0 +1,405 @@
use crate::core::entity::Entity;
use crate::storage::component_storage::ComponentStorageManager;
use crate::core::component::Component;
use crate::utils::IdentifierPool;
use rustc_hash::FxHashMap;
/**
* 实体管理器
* 提供统一的实体管理和查询机制,支持高效的实体操作
* 使用IdentifierPool进行世代式ID管理防止悬空引用
*/
pub struct EntityManager {
entities: FxHashMap<u32, Entity>,
entities_by_name: FxHashMap<String, Vec<u32>>,
entities_by_tag: FxHashMap<u32, Vec<u32>>,
id_pool: IdentifierPool,
destroyed_entities: std::collections::HashSet<u32>,
component_storage_manager: ComponentStorageManager,
}
impl EntityManager {
/**
* 创建实体管理器实例
*/
pub fn new() -> Self {
Self {
entities: FxHashMap::default(),
entities_by_name: FxHashMap::default(),
entities_by_tag: FxHashMap::default(),
id_pool: IdentifierPool::with_defaults(),
destroyed_entities: std::collections::HashSet::new(),
component_storage_manager: ComponentStorageManager::new(),
}
}
/**
* 获取实体总数
*/
pub fn entity_count(&self) -> usize {
self.entities.len()
}
/**
* 获取激活状态的实体数量
*/
pub fn active_entity_count(&self) -> usize {
self.entities
.values()
.filter(|entity| entity.active() && !entity.is_destroyed())
.count()
}
/**
* 创建新实体
* @param name 实体名称如果未指定则使用实体ID生成默认名称
* @returns 创建的实体ID世代式ID
*/
pub fn create_entity(&mut self, name: Option<String>) -> u32 {
let id = match self.id_pool.check_out() {
Ok(id) => id,
Err(e) => {
// ID池已满记录错误并返回一个无效ID
eprintln!("Failed to create entity: {}", e);
return u32::MAX; // 返回无效ID作为错误标识
}
};
let entity_name = name.unwrap_or_else(|| format!("Entity_{}", id));
let mut entity = Entity::new(id);
entity.set_name(entity_name.clone());
self.entities.insert(id, entity);
self.update_name_index(id, &entity_name, true);
self.update_tag_index(id, 0, true);
id
}
/**
* 批量创建实体
* @param count 要创建的实体数量
* @param name_prefix 实体名称前缀,默认为 Entity
* @returns 创建的实体ID数组
*/
pub fn create_entities_batch(&mut self, count: u32, name_prefix: Option<String>) -> Vec<u32> {
if count == 0 {
return Vec::new();
}
let prefix = name_prefix.unwrap_or_else(|| "Entity".to_string());
let mut entity_ids = Vec::with_capacity(count as usize);
for _ in 0..count {
let id = match self.id_pool.check_out() {
Ok(id) => id,
Err(e) => {
eprintln!("Failed to create entity in batch: {}", e);
break; // 停止创建更多实体
}
};
let entity_name = format!("{}_{}", prefix, id);
let mut entity = Entity::new(id);
entity.set_name(entity_name.clone());
entity_ids.push(id);
self.entities.insert(id, entity);
}
for &id in &entity_ids {
if let Some(entity) = self.entities.get(&id) {
let name = entity.name.clone();
let tag = entity.tag();
self.update_name_index(id, &name, true);
self.update_tag_index(id, tag, true);
}
}
entity_ids
}
/**
* 销毁实体
* @param entity_id 要销毁的实体ID
* @returns 是否成功销毁实体
*/
pub fn destroy_entity(&mut self, entity_id: u32) -> bool {
// 首先验证ID是否有效
if !self.id_pool.is_valid(entity_id) {
return false;
}
if let Some(mut entity) = self.entities.remove(&entity_id) {
self.destroyed_entities.insert(entity_id);
self.update_name_index(entity_id, &entity.name, false);
self.update_tag_index(entity_id, entity.tag(), false);
self.component_storage_manager.remove_all_components(entity_id);
entity.destroy();
// 回收ID到池中
self.id_pool.check_in(entity_id);
true
} else {
false
}
}
/**
* 获取所有实体ID
*/
pub fn get_all_entity_ids(&self) -> Vec<u32> {
self.entities.keys().copied().collect()
}
/**
* 根据ID获取实体
* @param id 实体ID
* @returns 对应的实体引用如果不存在则返回None
*/
pub fn get_entity(&self, id: u32) -> Option<&Entity> {
self.entities.get(&id)
}
/**
* 根据ID获取可变实体
* @param id 实体ID
* @returns 对应的可变实体引用如果不存在则返回None
*/
pub fn get_entity_mut(&mut self, id: u32) -> Option<&mut Entity> {
self.entities.get_mut(&id)
}
/**
* 根据名称获取实体
* @param name 实体名称
* @returns 匹配的实体ID如果不存在则返回None
*/
pub fn get_entity_by_name(&self, name: &str) -> Option<u32> {
self.entities_by_name
.get(name)
.and_then(|entities| entities.first())
.copied()
}
/**
* 根据标签获取实体列表
* @param tag 标签值
* @returns 具有指定标签的实体ID数组
*/
pub fn get_entities_by_tag(&self, tag: u32) -> Vec<u32> {
self.entities_by_tag
.get(&tag)
.cloned()
.unwrap_or_else(Vec::new)
}
/**
* 为实体添加组件
* @param entity_id 实体ID
* @param component 组件实例
*/
pub fn add_component<T: Component + Clone + 'static>(&mut self, entity_id: u32, component: T) -> Result<(), String> {
if !self.entities.contains_key(&entity_id) {
return Err(format!("Entity {} does not exist", entity_id));
}
self.component_storage_manager.add_component(entity_id, component)?;
if let Some(entity) = self.entities.get_mut(&entity_id) {
let mask = self.component_storage_manager.get_component_mask(entity_id);
entity.set_component_mask(mask);
}
Ok(())
}
/**
* 获取实体的组件位掩码
* @param entity_id 实体ID
* @returns 组件位掩码
*/
pub fn get_component_mask(&self, entity_id: u32) -> u64 {
self.component_storage_manager.get_component_mask(entity_id)
}
/**
* 获取组件存储管理器
*/
pub fn get_component_storage_manager(&self) -> &ComponentStorageManager {
&self.component_storage_manager
}
/**
* 获取可变组件存储管理器
*/
pub fn get_component_storage_manager_mut(&mut self) -> &mut ComponentStorageManager {
&mut self.component_storage_manager
}
/**
* 更新名称索引
* @param entity_id 实体ID
* @param name 实体名称
* @param is_add true表示添加到索引false表示从索引中移除
*/
fn update_name_index(&mut self, entity_id: u32, name: &str, is_add: bool) {
if is_add {
self.entities_by_name
.entry(name.to_string())
.or_insert_with(Vec::new)
.push(entity_id);
} else {
if let Some(entities) = self.entities_by_name.get_mut(name) {
entities.retain(|&id| id != entity_id);
if entities.is_empty() {
self.entities_by_name.remove(name);
}
}
}
}
/**
* 更新标签索引
* @param entity_id 实体ID
* @param tag 标签值
* @param is_add true表示添加到索引false表示从索引中移除
*/
fn update_tag_index(&mut self, entity_id: u32, tag: u32, is_add: bool) {
if is_add {
self.entities_by_tag
.entry(tag)
.or_insert_with(Vec::new)
.push(entity_id);
} else {
if let Some(entities) = self.entities_by_tag.get_mut(&tag) {
entities.retain(|&id| id != entity_id);
if entities.is_empty() {
self.entities_by_tag.remove(&tag);
}
}
}
}
// ========== IdentifierPool相关方法 ==========
/**
* 验证实体ID是否有效考虑世代版本
* @param entity_id 要验证的实体ID
* @returns 是否为有效的ID
*/
pub fn is_entity_id_valid(&self, entity_id: u32) -> bool {
self.id_pool.is_valid(entity_id)
}
/**
* 强制处理延迟回收的ID
* 在某些情况下可能需要立即处理延迟回收队列
*/
pub fn force_process_delayed_recycle(&mut self) {
self.id_pool.force_process_delayed_recycle();
}
/**
* 获取IdentifierPool统计信息
* 用于调试和性能监控
*/
pub fn get_id_pool_stats(&self) -> crate::utils::IdentifierPoolStats {
self.id_pool.get_stats()
}
/**
* 检查实体是否存在且有效
* 结合ID有效性检查和实际存在性检查
*/
pub fn entity_exists_and_valid(&self, entity_id: u32) -> bool {
self.id_pool.is_valid(entity_id) && self.entities.contains_key(&entity_id)
}
/**
* 获取有效实体的数量
* 只计算ID有效且实际存在的实体
*/
pub fn valid_entity_count(&self) -> usize {
self.entities.iter()
.filter(|(&id, _)| self.id_pool.is_valid(id))
.count()
}
/**
* 清理所有无效的实体引用
* 清理那些ID已经无效的实体记录
*/
pub fn cleanup_invalid_entities(&mut self) {
let invalid_ids: Vec<u32> = self.entities.keys()
.filter(|&&id| !self.id_pool.is_valid(id))
.copied()
.collect();
for id in invalid_ids {
if let Some(entity) = self.entities.remove(&id) {
// 从索引中清理
self.update_name_index(id, &entity.name, false);
self.update_tag_index(id, entity.tag(), false);
// 从销毁实体集合中清理
self.destroyed_entities.remove(&id);
}
}
}
/**
* 获取调试信息包含ID池统计
*/
pub fn get_debug_info(&self) -> String {
let id_stats = self.id_pool.get_stats();
format!(
"{{\"entities\":{},\"active_entities\":{},\"valid_entities\":{},\"destroyed_entities\":{},\"id_pool\":{{\"total_allocated\":{},\"current_active\":{},\"pending_recycle\":{},\"memory_usage\":{}}}}}",
self.entity_count(),
self.active_entity_count(),
self.valid_entity_count(),
self.destroyed_entities.len(),
id_stats.total_allocated,
id_stats.current_active,
id_stats.pending_recycle,
id_stats.memory_usage
)
}
/**
* 添加实体到管理器
*/
pub fn add_entity(&mut self, mut entity: Entity) {
let entity_id = if entity.id() == 0 {
// 如果实体ID为0分配新ID
let new_id = self.id_pool.check_out().unwrap_or(0);
entity.set_id(new_id);
new_id
} else {
entity.id()
};
// 如果实体有名称,添加到名称索引
if let Some(name) = entity.name() {
self.entities_by_name.entry(name.clone()).or_insert_with(Vec::new).push(entity_id);
}
// 如果实体有标签,添加到标签索引
for tag in &entity.tags() {
self.entities_by_tag.entry(*tag).or_insert_with(Vec::new).push(entity_id);
}
self.entities.insert(entity_id, entity);
}
/**
* 预留容量
*/
pub fn reserve_capacity(&mut self, capacity: usize) {
self.entities.reserve(capacity);
self.entities_by_name.reserve(capacity / 10); // 假设10%的实体有名称
self.entities_by_tag.reserve(capacity / 5); // 假设20%的实体有标签
}
}

View File

@@ -0,0 +1,574 @@
use std::collections::HashMap;
use std::any::Any;
/**
* ECS事件类型
* 定义实体组件系统中的核心事件类型
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ECSEventType {
// 实体相关事件
EntityCreated,
EntityDestroyed,
EntityEnabled,
EntityDisabled,
EntityTagChanged,
EntityNameChanged,
// 组件相关事件
ComponentAdded,
ComponentRemoved,
ComponentModified,
ComponentEnabled,
ComponentDisabled,
// 系统相关事件
SystemAdded,
SystemRemoved,
SystemEnabled,
SystemDisabled,
SystemProcessingStart,
SystemProcessingEnd,
SystemError,
// 场景相关事件
SceneCreated,
SceneDestroyed,
SceneActivated,
SceneDeactivated,
// 性能相关事件
PerformanceWarning,
PerformanceCritical,
MemoryUsageHigh,
// 查询相关事件
QueryExecuted,
QueryCacheHit,
QueryCacheMiss,
}
impl ECSEventType {
/**
* 转换为字符串表示
*/
pub fn as_str(&self) -> &'static str {
match self {
ECSEventType::EntityCreated => "entity:created",
ECSEventType::EntityDestroyed => "entity:destroyed",
ECSEventType::EntityEnabled => "entity:enabled",
ECSEventType::EntityDisabled => "entity:disabled",
ECSEventType::EntityTagChanged => "entity:tag:changed",
ECSEventType::EntityNameChanged => "entity:name:changed",
ECSEventType::ComponentAdded => "component:added",
ECSEventType::ComponentRemoved => "component:removed",
ECSEventType::ComponentModified => "component:modified",
ECSEventType::ComponentEnabled => "component:enabled",
ECSEventType::ComponentDisabled => "component:disabled",
ECSEventType::SystemAdded => "system:added",
ECSEventType::SystemRemoved => "system:removed",
ECSEventType::SystemEnabled => "system:enabled",
ECSEventType::SystemDisabled => "system:disabled",
ECSEventType::SystemProcessingStart => "system:processing:start",
ECSEventType::SystemProcessingEnd => "system:processing:end",
ECSEventType::SystemError => "system:error",
ECSEventType::SceneCreated => "scene:created",
ECSEventType::SceneDestroyed => "scene:destroyed",
ECSEventType::SceneActivated => "scene:activated",
ECSEventType::SceneDeactivated => "scene:deactivated",
ECSEventType::PerformanceWarning => "performance:warning",
ECSEventType::PerformanceCritical => "performance:critical",
ECSEventType::MemoryUsageHigh => "memory:usage:high",
ECSEventType::QueryExecuted => "query:executed",
ECSEventType::QueryCacheHit => "query:cache:hit",
ECSEventType::QueryCacheMiss => "query:cache:miss",
}
}
}
/**
* 事件优先级
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum EventPriority {
Lowest = 0,
Low = 25,
Normal = 50,
High = 75,
Highest = 100,
Critical = 200,
}
/**
* 事件数据
* 包含事件的所有信息
*/
#[derive(Debug)]
pub struct Event {
pub event_type: ECSEventType,
pub priority: EventPriority,
pub timestamp: u64,
pub entity_id: Option<u32>,
pub data: Option<Box<dyn Any + Send + Sync>>,
pub metadata: HashMap<String, String>,
}
impl Event {
/**
* 创建新事件
*/
pub fn new(event_type: ECSEventType, priority: EventPriority) -> Self {
Self {
event_type,
priority,
timestamp: current_timestamp(),
entity_id: None,
data: None,
metadata: HashMap::new(),
}
}
/**
* 设置实体ID
*/
pub fn with_entity_id(mut self, entity_id: u32) -> Self {
self.entity_id = Some(entity_id);
self
}
/**
* 设置事件数据
*/
pub fn with_data<T: Any + Send + Sync>(mut self, data: T) -> Self {
self.data = Some(Box::new(data));
self
}
/**
* 添加元数据
*/
pub fn with_metadata<K: Into<String>, V: Into<String>>(mut self, key: K, value: V) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
/**
* 获取类型化的数据
*/
pub fn get_data<T: Any>(&self) -> Option<&T> {
self.data.as_ref()?.downcast_ref::<T>()
}
/**
* 获取元数据
*/
pub fn get_metadata(&self, key: &str) -> Option<&String> {
self.metadata.get(key)
}
}
/**
* 事件监听器trait
*/
pub trait EventListener: Send + Sync {
/**
* 处理事件
*/
fn handle_event(&mut self, event: &Event);
/**
* 获取监听器感兴趣的事件类型
*/
fn get_interested_events(&self) -> Vec<ECSEventType>;
/**
* 获取监听器优先级
*/
fn get_priority(&self) -> EventPriority {
EventPriority::Normal
}
/**
* 检查是否应该处理此事件
*/
fn should_handle(&self, event: &Event) -> bool {
self.get_interested_events().contains(&event.event_type)
}
}
/**
* 事件回调函数类型
*/
pub type EventCallback = Box<dyn Fn(&Event) + Send + Sync>;
/**
* 监听器注册信息
*/
struct ListenerRegistration {
callback: EventCallback,
id: u32,
priority: EventPriority,
}
/**
* 事件总线
* 负责事件的分发和监听器管理
*/
pub struct EventBus {
listeners: HashMap<ECSEventType, Vec<ListenerRegistration>>,
next_listener_id: u32,
event_queue: Vec<Event>,
stats: EventBusStats,
}
/**
* 事件总线统计信息
*/
#[derive(Debug, Default)]
pub struct EventBusStats {
pub total_events_fired: u64,
pub total_listeners_notified: u64,
pub events_by_type: HashMap<ECSEventType, u32>,
pub listener_count: u32,
pub queue_size: usize,
}
impl EventBus {
/**
* 创建新的事件总线
*/
pub fn new() -> Self {
Self {
listeners: HashMap::new(),
next_listener_id: 1,
event_queue: Vec::new(),
stats: EventBusStats::default(),
}
}
/**
* 注册事件回调函数
*/
pub fn register_callback<F>(&mut self, event_type: ECSEventType, callback: F, priority: EventPriority) -> u32
where
F: Fn(&Event) + Send + Sync + 'static,
{
let id = self.next_listener_id;
self.next_listener_id += 1;
let registration = ListenerRegistration {
callback: Box::new(callback),
id,
priority,
};
let listeners = self.listeners.entry(event_type).or_insert_with(Vec::new);
listeners.push(registration);
// 按优先级排序
listeners.sort_by(|a, b| b.priority.cmp(&a.priority));
self.stats.listener_count += 1;
id
}
/**
* 注册多个事件类型的回调
*/
pub fn register_callback_multi<F>(&mut self, event_types: Vec<ECSEventType>, callback: F, priority: EventPriority) -> Vec<u32>
where
F: Fn(&Event) + Send + Sync + Clone + 'static,
{
let mut ids = Vec::new();
for event_type in event_types {
let id = self.register_callback(event_type, callback.clone(), priority);
ids.push(id);
}
ids
}
/**
* 注销事件监听器
*/
pub fn unregister_callback(&mut self, listener_id: u32) -> bool {
let mut found = false;
for listeners in self.listeners.values_mut() {
listeners.retain(|reg| {
if reg.id == listener_id {
found = true;
false
} else {
true
}
});
}
if found {
self.stats.listener_count -= 1;
}
found
}
/**
* 立即触发事件
*/
pub fn fire_event(&mut self, event: Event) {
self.stats.total_events_fired += 1;
*self.stats.events_by_type.entry(event.event_type).or_insert(0) += 1;
if let Some(listeners) = self.listeners.get(&event.event_type) {
for registration in listeners {
(registration.callback)(&event);
self.stats.total_listeners_notified += 1;
}
}
}
/**
* 将事件添加到队列(延迟处理)
*/
pub fn queue_event(&mut self, event: Event) {
self.event_queue.push(event);
self.stats.queue_size = self.event_queue.len();
}
/**
* 处理队列中的所有事件
*/
pub fn process_queued_events(&mut self) {
let events = std::mem::take(&mut self.event_queue);
for event in events {
self.fire_event(event);
}
self.stats.queue_size = 0;
}
/**
* 清空事件队列
*/
pub fn clear_queue(&mut self) {
self.event_queue.clear();
self.stats.queue_size = 0;
}
/**
* 获取统计信息
*/
pub fn get_stats(&self) -> &EventBusStats {
&self.stats
}
/**
* 检查是否有指定类型的监听器
*/
pub fn has_listeners(&self, event_type: ECSEventType) -> bool {
self.listeners.get(&event_type).map_or(false, |listeners| !listeners.is_empty())
}
/**
* 获取指定事件类型的监听器数量
*/
pub fn get_listener_count(&self, event_type: ECSEventType) -> usize {
self.listeners.get(&event_type).map_or(0, |listeners| listeners.len())
}
}
impl Default for EventBus {
fn default() -> Self {
Self::new()
}
}
/**
* 简单的事件监听器实现
*/
pub struct SimpleEventListener<F>
where
F: Fn(&Event) + Send + Sync,
{
handler: F,
interested_events: Vec<ECSEventType>,
priority: EventPriority,
}
impl<F> SimpleEventListener<F>
where
F: Fn(&Event) + Send + Sync,
{
/**
* 创建简单的事件监听器
*/
pub fn new(handler: F, interested_events: Vec<ECSEventType>) -> Self {
Self {
handler,
interested_events,
priority: EventPriority::Normal,
}
}
/**
* 设置优先级
*/
pub fn with_priority(mut self, priority: EventPriority) -> Self {
self.priority = priority;
self
}
}
impl<F> EventListener for SimpleEventListener<F>
where
F: Fn(&Event) + Send + Sync,
{
fn handle_event(&mut self, event: &Event) {
(self.handler)(event);
}
fn get_interested_events(&self) -> Vec<ECSEventType> {
self.interested_events.clone()
}
fn get_priority(&self) -> EventPriority {
self.priority
}
}
/**
* 获取当前时间戳(毫秒)
*/
fn current_timestamp() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
#[test]
fn test_event_creation() {
let event = Event::new(ECSEventType::EntityCreated, EventPriority::Normal)
.with_entity_id(42)
.with_data("test data".to_string())
.with_metadata("key", "value");
assert_eq!(event.event_type, ECSEventType::EntityCreated);
assert_eq!(event.priority, EventPriority::Normal);
assert_eq!(event.entity_id, Some(42));
assert_eq!(event.get_data::<String>(), Some(&"test data".to_string()));
assert_eq!(event.get_metadata("key"), Some(&"value".to_string()));
}
#[test]
fn test_event_bus_basic() {
let mut event_bus = EventBus::new();
let events_received = Arc::new(Mutex::new(Vec::new()));
let events_clone = events_received.clone();
// 注册回调
let listener_id = event_bus.register_callback(
ECSEventType::EntityCreated,
move |event: &Event| {
if let Ok(mut events) = events_clone.lock() {
events.push(event.event_type);
}
},
EventPriority::Normal,
);
// 触发事件
let event = Event::new(ECSEventType::EntityCreated, EventPriority::Normal)
.with_entity_id(123);
event_bus.fire_event(event);
// 验证事件被接收
let events = events_received.lock().unwrap();
assert_eq!(events.len(), 1);
assert_eq!(events[0], ECSEventType::EntityCreated);
// 验证统计信息
let stats = event_bus.get_stats();
assert_eq!(stats.total_events_fired, 1);
assert_eq!(stats.total_listeners_notified, 1);
// 注销监听器
assert!(event_bus.unregister_callback(listener_id));
assert!(!event_bus.unregister_callback(listener_id)); // 重复注销应该失败
}
#[test]
fn test_event_queue() {
let mut event_bus = EventBus::new();
let events_received = Arc::new(Mutex::new(Vec::new()));
let events_clone1 = events_received.clone();
let events_clone2 = events_received.clone();
event_bus.register_callback(
ECSEventType::EntityCreated,
move |event: &Event| {
if let Ok(mut events) = events_clone1.lock() {
events.push(event.event_type);
}
},
EventPriority::Normal,
);
event_bus.register_callback(
ECSEventType::EntityDestroyed,
move |event: &Event| {
if let Ok(mut events) = events_clone2.lock() {
events.push(event.event_type);
}
},
EventPriority::Normal,
);
// 将事件加入队列
let event1 = Event::new(ECSEventType::EntityCreated, EventPriority::Normal);
let event2 = Event::new(ECSEventType::EntityDestroyed, EventPriority::Normal);
event_bus.queue_event(event1);
event_bus.queue_event(event2);
// 此时事件还没有被处理
let events = events_received.lock().unwrap();
assert_eq!(events.len(), 0);
drop(events);
// 处理队列中的事件
event_bus.process_queued_events();
let events = events_received.lock().unwrap();
assert_eq!(events.len(), 2);
assert_eq!(events[0], ECSEventType::EntityCreated);
assert_eq!(events[1], ECSEventType::EntityDestroyed);
}
#[test]
fn test_simple_event_listener() {
let mut event_bus = EventBus::new();
let received_events = Arc::new(Mutex::new(Vec::new()));
let events_clone = received_events.clone();
event_bus.register_callback(
ECSEventType::ComponentAdded,
move |event: &Event| {
if let Ok(mut events) = events_clone.lock() {
events.push(event.event_type);
}
},
EventPriority::Normal,
);
let event = Event::new(ECSEventType::ComponentAdded, EventPriority::Normal);
event_bus.fire_event(event);
let events = received_events.lock().unwrap();
assert_eq!(events.len(), 1);
assert_eq!(events[0], ECSEventType::ComponentAdded);
}
}

View File

@@ -0,0 +1,584 @@
use crate::core::Entity;
use crate::utils::ComponentType;
/**
* 实体构建器
* 提供流式API创建和配置实体
*/
pub struct EntityBuilder {
entity: Entity,
scene_id: Option<u32>,
}
impl EntityBuilder {
/**
* 创建新的实体构建器
*/
pub fn new(name: &str, entity_id: u32) -> Self {
let mut entity = Entity::new(entity_id);
entity.set_name(name.to_string());
Self {
entity,
scene_id: None,
}
}
/**
* 设置实体名称
*/
pub fn named(mut self, name: &str) -> Self {
self.entity.name = name.to_string();
self
}
/**
* 设置实体标签
*/
pub fn tagged(mut self, tag: u32) -> Self {
self.entity.set_tag(tag);
self
}
/**
* 设置实体为启用状态
*/
pub fn enabled(mut self, enabled: bool) -> Self {
self.entity.set_enabled(enabled);
self
}
/**
* 设置实体为活跃状态
*/
pub fn active(mut self, active: bool) -> Self {
self.entity.set_active(active);
self
}
/**
* 设置更新顺序
*/
pub fn with_update_order(mut self, order: i32) -> Self {
self.entity.set_update_order(order);
self
}
/**
* 添加子实体ID
*/
pub fn with_child(mut self, child_id: u32) -> Self {
let _ = self.entity.add_child_id(child_id);
self
}
/**
* 批量添加子实体ID
*/
pub fn with_children(mut self, child_ids: Vec<u32>) -> Self {
for child_id in child_ids {
let _ = self.entity.add_child_id(child_id);
}
self
}
/**
* 条件性设置属性
*/
pub fn with_if<F>(self, condition: bool, func: F) -> Self
where
F: FnOnce(Self) -> Self,
{
if condition {
func(self)
} else {
self
}
}
/**
* 获取构建的实体消耗builder
*/
pub fn build(self) -> Entity {
self.entity
}
/**
* 获取实体的引用
*/
pub fn get_entity(&self) -> &Entity {
&self.entity
}
/**
* 获取实体的可变引用
*/
pub fn get_entity_mut(&mut self) -> &mut Entity {
&mut self.entity
}
/**
* 克隆构建器
*/
pub fn clone_builder(&self, new_entity_id: u32) -> Self {
// 由于Entity没有实现Clone我们创建一个新的Entity
let mut new_entity = Entity::new(new_entity_id);
if let Some(name) = self.entity.name() {
new_entity.set_name(name);
}
new_entity.set_tag(self.entity.tag());
new_entity.set_active(self.entity.active());
new_entity.set_enabled(self.entity.enabled());
new_entity.set_update_order(self.entity.update_order());
Self {
entity: new_entity,
scene_id: self.scene_id,
}
}
}
/**
* 查询构建器
* 提供流式API构建复杂查询
*/
pub struct QueryBuilder {
component_types: Vec<ComponentType>,
any_component_types: Vec<ComponentType>,
none_component_types: Vec<ComponentType>,
tag_filter: Option<u32>,
name_filter: Option<String>,
active_only: bool,
enabled_only: bool,
}
impl QueryBuilder {
/**
* 创建新的查询构建器
*/
pub fn new() -> Self {
Self {
component_types: Vec::new(),
any_component_types: Vec::new(),
none_component_types: Vec::new(),
tag_filter: None,
name_filter: None,
active_only: false,
enabled_only: false,
}
}
/**
* 添加必须包含的组件类型
*/
pub fn with_component(mut self, component_type: ComponentType) -> Self {
self.component_types.push(component_type);
self
}
/**
* 添加多个必须包含的组件类型
*/
pub fn with_components(mut self, component_types: Vec<ComponentType>) -> Self {
self.component_types.extend(component_types);
self
}
/**
* 添加任意一个包含的组件类型
*/
pub fn with_any_component(mut self, component_type: ComponentType) -> Self {
self.any_component_types.push(component_type);
self
}
/**
* 添加多个任意一个包含的组件类型
*/
pub fn with_any_components(mut self, component_types: Vec<ComponentType>) -> Self {
self.any_component_types.extend(component_types);
self
}
/**
* 添加必须不包含的组件类型
*/
pub fn without_component(mut self, component_type: ComponentType) -> Self {
self.none_component_types.push(component_type);
self
}
/**
* 添加多个必须不包含的组件类型
*/
pub fn without_components(mut self, component_types: Vec<ComponentType>) -> Self {
self.none_component_types.extend(component_types);
self
}
/**
* 按标签过滤
*/
pub fn with_tag(mut self, tag: u32) -> Self {
self.tag_filter = Some(tag);
self
}
/**
* 按名称过滤
*/
pub fn with_name(mut self, name: &str) -> Self {
self.name_filter = Some(name.to_string());
self
}
/**
* 只查询活跃实体
*/
pub fn active_only(mut self) -> Self {
self.active_only = true;
self
}
/**
* 只查询启用实体
*/
pub fn enabled_only(mut self) -> Self {
self.enabled_only = true;
self
}
/**
* 获取所有查询条件
*/
pub fn get_all_components(&self) -> &Vec<ComponentType> {
&self.component_types
}
/**
* 获取任意查询条件
*/
pub fn get_any_components(&self) -> &Vec<ComponentType> {
&self.any_component_types
}
/**
* 获取排除查询条件
*/
pub fn get_none_components(&self) -> &Vec<ComponentType> {
&self.none_component_types
}
/**
* 获取标签过滤器
*/
pub fn get_tag_filter(&self) -> Option<u32> {
self.tag_filter
}
/**
* 获取名称过滤器
*/
pub fn get_name_filter(&self) -> Option<&String> {
self.name_filter.as_ref()
}
/**
* 是否只查询活跃实体
*/
pub fn is_active_only(&self) -> bool {
self.active_only
}
/**
* 是否只查询启用实体
*/
pub fn is_enabled_only(&self) -> bool {
self.enabled_only
}
}
impl Default for QueryBuilder {
fn default() -> Self {
Self::new()
}
}
/**
* 流式API统计信息
*/
#[derive(Debug, Clone)]
pub struct FluentAPIStats {
/// 创建的实体构建器数量
pub entity_builders_created: u32,
/// 创建的查询构建器数量
pub query_builders_created: u32,
/// 执行的批量操作数量
pub batch_operations_executed: u32,
/// 使用的工厂函数数量
pub factory_functions_used: u32,
/// 条件操作执行次数
pub conditional_operations: u32,
}
impl Default for FluentAPIStats {
fn default() -> Self {
Self {
entity_builders_created: 0,
query_builders_created: 0,
batch_operations_executed: 0,
factory_functions_used: 0,
conditional_operations: 0,
}
}
}
/**
* ECS流式API主入口
* 提供统一的流式接口
*/
pub struct ECSFluentAPI {
/// 统计信息
stats: FluentAPIStats,
}
impl ECSFluentAPI {
/**
* 创建新的流式API实例
*/
pub fn new() -> Self {
Self {
stats: FluentAPIStats::default(),
}
}
/**
* 创建实体构建器
*/
pub fn create_entity(&mut self, name: &str, entity_id: u32) -> EntityBuilder {
self.stats.entity_builders_created += 1;
EntityBuilder::new(name, entity_id)
}
/**
* 创建查询构建器
*/
pub fn query(&mut self) -> QueryBuilder {
self.stats.query_builders_created += 1;
QueryBuilder::new()
}
/**
* 条件性执行操作
*/
pub fn when<F, T>(&mut self, condition: bool, operation: F) -> Option<T>
where
F: FnOnce() -> T,
{
self.stats.conditional_operations += 1;
if condition {
Some(operation())
} else {
None
}
}
/**
* 批量创建实体
*/
pub fn create_entities_batch(
&mut self,
count: u32,
name_prefix: &str,
start_id: u32,
) -> Vec<EntityBuilder> {
self.stats.batch_operations_executed += 1;
let mut builders = Vec::with_capacity(count as usize);
for i in 0..count {
let name = format!("{}_{}", name_prefix, i);
let builder = EntityBuilder::new(&name, start_id + i);
builders.push(builder);
}
self.stats.entity_builders_created += count;
builders
}
/**
* 使用工厂函数创建实体
*/
pub fn create_entity_with_factory<F>(
&mut self,
name: &str,
entity_id: u32,
factory: F,
) -> EntityBuilder
where
F: FnOnce(EntityBuilder) -> EntityBuilder,
{
self.stats.factory_functions_used += 1;
self.stats.entity_builders_created += 1;
let builder = EntityBuilder::new(name, entity_id);
factory(builder)
}
/**
* 获取统计信息
*/
pub fn get_stats(&self) -> FluentAPIStats {
self.stats.clone()
}
/**
* 重置统计信息
*/
pub fn reset_stats(&mut self) {
self.stats = FluentAPIStats::default();
}
/**
* 清空所有状态
*/
pub fn clear(&mut self) {
self.reset_stats();
}
}
impl Default for ECSFluentAPI {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::TypeId;
// 测试用的示例组件类型
struct TestComponentA;
struct TestComponentB;
struct TestComponentC;
#[test]
fn test_entity_builder_basic() {
let builder = EntityBuilder::new("test_entity", 1);
let entity = builder
.named("my_entity")
.tagged(42)
.enabled(true)
.active(true)
.with_update_order(10)
.build();
assert_eq!(entity.name, "my_entity");
assert_eq!(entity.tag(), 42);
assert_eq!(entity.enabled(), true);
assert_eq!(entity.active(), true);
assert_eq!(entity.update_order(), 10);
}
#[test]
fn test_entity_builder_children() {
let builder = EntityBuilder::new("parent", 1);
let entity = builder
.with_child(2)
.with_children(vec![3, 4, 5])
.build();
assert_eq!(entity.children_ids().len(), 4);
assert_eq!(entity.children_ids(), &[2, 3, 4, 5]);
}
#[test]
fn test_entity_builder_conditional() {
let builder = EntityBuilder::new("test", 1);
let entity = builder
.with_if(true, |b| b.tagged(100))
.with_if(false, |b| b.tagged(200))
.build();
assert_eq!(entity.tag(), 100);
}
#[test]
fn test_query_builder() {
let query = QueryBuilder::new()
.with_component(TypeId::of::<TestComponentA>())
.with_components(vec![
TypeId::of::<TestComponentB>(),
TypeId::of::<TestComponentC>(),
])
.with_any_component(TypeId::of::<TestComponentA>())
.without_component(TypeId::of::<TestComponentB>())
.with_tag(42)
.with_name("test")
.active_only()
.enabled_only();
assert_eq!(query.get_all_components().len(), 3);
assert_eq!(query.get_any_components().len(), 1);
assert_eq!(query.get_none_components().len(), 1);
assert_eq!(query.get_tag_filter(), Some(42));
assert_eq!(query.get_name_filter(), Some(&"test".to_string()));
assert!(query.is_active_only());
assert!(query.is_enabled_only());
}
#[test]
fn test_fluent_api_basic() {
let mut api = ECSFluentAPI::new();
let _builder = api.create_entity("test", 1);
let _query = api.query();
let stats = api.get_stats();
assert_eq!(stats.entity_builders_created, 1);
assert_eq!(stats.query_builders_created, 1);
}
#[test]
fn test_fluent_api_batch() {
let mut api = ECSFluentAPI::new();
let builders = api.create_entities_batch(5, "entity", 100);
assert_eq!(builders.len(), 5);
let stats = api.get_stats();
assert_eq!(stats.entity_builders_created, 5);
assert_eq!(stats.batch_operations_executed, 1);
}
#[test]
fn test_fluent_api_factory() {
let mut api = ECSFluentAPI::new();
let entity = api
.create_entity_with_factory("test", 1, |builder| {
builder.tagged(42).enabled(true)
})
.build();
assert_eq!(entity.tag(), 42);
assert_eq!(entity.enabled(), true);
let stats = api.get_stats();
assert_eq!(stats.factory_functions_used, 1);
assert_eq!(stats.entity_builders_created, 1);
}
#[test]
fn test_fluent_api_conditional() {
let mut api = ECSFluentAPI::new();
let result1 = api.when(true, || "executed");
let result2 = api.when(false, || "not executed");
assert_eq!(result1, Some("executed"));
assert_eq!(result2, None);
let stats = api.get_stats();
assert_eq!(stats.conditional_operations, 2);
}
}

View File

@@ -0,0 +1,27 @@
pub mod entity;
pub mod component;
pub mod entity_manager;
pub mod query_system;
pub mod scene;
pub mod systems;
pub mod events;
pub mod archetype_system;
pub mod fluent_api;
pub mod passive_system;
pub mod component_builder;
pub mod entity_batch_operator;
pub mod scene_builder;
pub use entity::Entity;
pub use component::{Component, ComponentRegistry, BaseComponent};
pub use entity_manager::EntityManager;
pub use query_system::{QuerySystem, QueryResult};
pub use scene::Scene;
pub use systems::{System, EntitySystem, ProcessingSystem, IntervalSystem, SystemManager};
pub use events::{ECSEventType, EventPriority, Event, EventListener, EventBus, EventBusStats, SimpleEventListener};
pub use archetype_system::{ArchetypeSystem, Archetype, ArchetypeId, ArchetypeQueryResult, ArchetypeSystemStats};
pub use fluent_api::{EntityBuilder, QueryBuilder, ECSFluentAPI, FluentAPIStats};
pub use passive_system::{PassiveSystem, PassiveSystemBuilder};
pub use component_builder::{ComponentBuilder, BaseComponentBuilder, ComponentBuilderFactory, ComponentBuilderStats};
pub use entity_batch_operator::{EntityBatchOperator, BatchOperatorStats};
pub use scene_builder::{SceneBuilder, SceneTemplate, SceneBuilderStats, SceneBuilderFactory, SceneBuilderManager};

View File

@@ -0,0 +1,351 @@
use crate::core::Entity;
use crate::core::systems::{System, SystemContext};
use crate::utils::{Matcher, Time};
/**
* 被动实体系统
*
* 定义一个被动的实体系统继承自EntitySystem类。
* 被动的实体系统不会对实体进行任何修改,只会被动地接收实体的变化事件。
* 主要用于监听、记录或收集数据的场景。
*/
pub struct PassiveSystem {
pub matcher: Option<Matcher>,
pub priority: i32,
pub enabled: bool,
pub name: String,
}
impl PassiveSystem {
/**
* 创建新的被动系统
*/
pub fn new(name: String, matcher: Option<Matcher>) -> Self {
Self {
matcher,
priority: 0,
enabled: true,
name,
}
}
/**
* 设置系统优先级
*/
pub fn with_priority(mut self, priority: i32) -> Self {
self.priority = priority;
self
}
/**
* 设置系统启用状态
*/
pub fn with_enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
/**
* 获取系统名称
*/
pub fn get_name(&self) -> &str {
&self.name
}
/**
* 获取匹配器
*/
pub fn get_matcher(&self) -> Option<&Matcher> {
self.matcher.as_ref()
}
/**
* 检查是否启用
*/
pub fn is_enabled(&self) -> bool {
self.enabled
}
/**
* 设置启用状态
*/
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
/**
* 获取优先级
*/
pub fn get_priority(&self) -> i32 {
self.priority
}
/**
* 设置优先级
*/
pub fn set_priority(&mut self, priority: i32) {
self.priority = priority;
}
/**
* 系统初始化
* 子类可以重写此方法进行自定义初始化
*/
pub fn initialize(&mut self) {
// 默认空实现,子类可以重写
}
/**
* 系统更新前调用
* 子类可以重写此方法进行预处理
*/
pub fn before_update(&mut self, _time: &Time) {
// 默认空实现,子类可以重写
}
/**
* 系统更新后调用
* 子类可以重写此方法进行后处理
*/
pub fn after_update(&mut self, _time: &Time) {
// 默认空实现,子类可以重写
}
/**
* 系统清理
* 子类可以重写此方法进行清理工作
*/
pub fn cleanup(&mut self) {
// 默认空实现,子类可以重写
}
/**
* 实体添加通知
* 当匹配的实体被添加到系统时调用
*/
pub fn on_entity_added(&mut self, _entity: &Entity) {
// 默认空实现,子类可以重写进行处理
}
/**
* 实体移除通知
* 当匹配的实体从系统中移除时调用
*/
pub fn on_entity_removed(&mut self, _entity: &Entity) {
// 默认空实现,子类可以重写进行处理
}
/**
* 组件添加通知
* 当实体添加组件时调用
*/
pub fn on_component_added(&mut self, _entity: &Entity, _component_type: std::any::TypeId) {
// 默认空实现,子类可以重写进行处理
}
/**
* 组件移除通知
* 当实体移除组件时调用
*/
pub fn on_component_removed(&mut self, _entity: &Entity, _component_type: std::any::TypeId) {
// 默认空实现,子类可以重写进行处理
}
}
impl System for PassiveSystem {
fn update(&mut self, _context: &mut SystemContext) {
// 被动系统不进行任何处理
// 所有的业务逻辑都应该在事件处理方法中实现
}
fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
fn set_update_order(&mut self, order: i32) {
self.priority = order;
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
/**
* 被动系统构建器
* 提供链式调用构建被动系统
*/
pub struct PassiveSystemBuilder {
name: String,
matcher: Option<Matcher>,
priority: i32,
enabled: bool,
}
impl PassiveSystemBuilder {
/**
* 创建新的被动系统构建器
*/
pub fn new(name: String) -> Self {
Self {
name,
matcher: None,
priority: 0,
enabled: true,
}
}
/**
* 设置匹配器
*/
pub fn with_matcher(mut self, matcher: Matcher) -> Self {
self.matcher = Some(matcher);
self
}
/**
* 设置优先级
*/
pub fn with_priority(mut self, priority: i32) -> Self {
self.priority = priority;
self
}
/**
* 设置启用状态
*/
pub fn with_enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
/**
* 构建被动系统
*/
pub fn build(self) -> PassiveSystem {
PassiveSystem {
name: self.name,
matcher: self.matcher,
priority: self.priority,
enabled: self.enabled,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::{Entity, ComponentRegistry};
#[test]
fn test_passive_system_creation() {
let system = PassiveSystem::new("TestPassive".to_string(), None);
assert_eq!(system.get_name(), "TestPassive");
assert!(system.enabled());
assert_eq!(system.get_priority(), 0);
assert!(system.get_matcher().is_none());
}
#[test]
fn test_passive_system_builder() {
let system = PassiveSystemBuilder::new("TestPassive".to_string())
.with_priority(10)
.with_enabled(false)
.build();
assert_eq!(system.get_name(), "TestPassive");
assert!(!system.enabled());
assert_eq!(system.get_priority(), 10);
}
#[test]
fn test_passive_system_with_matcher() {
let matcher = Matcher::new();
let system = PassiveSystemBuilder::new("TestPassive".to_string())
.with_matcher(matcher)
.build();
assert!(system.get_matcher().is_some());
}
#[test]
fn test_passive_system_update_does_nothing() {
use crate::core::systems::{System, SystemContext};
use crate::core::EntityManager;
use crate::storage::ComponentStorageManager;
let mut system = PassiveSystem::new("TestPassive".to_string(), None);
let mut entity_manager = EntityManager::new();
let mut component_storage_manager = ComponentStorageManager::new();
let mut context = SystemContext {
entity_manager: &mut entity_manager,
component_storage_manager: &mut component_storage_manager,
};
// update方法不应该做任何事情
system.update(&mut context);
// 如果没有panic说明update方法正确地什么都没做
}
#[test]
fn test_passive_system_properties() {
let mut system = PassiveSystem::new("TestPassive".to_string(), None);
// 测试系统属性
assert!(system.enabled());
system.set_enabled(false);
assert!(!system.enabled());
assert_eq!(system.get_name(), "TestPassive");
assert_eq!(system.get_priority(), 0);
}
#[test]
fn test_passive_system_lifecycle() {
let mut system = PassiveSystem::new("TestPassive".to_string(), None);
let time = Time::new();
// 测试生命周期方法(都应该是安全的空操作)
system.initialize();
system.before_update(&time);
system.after_update(&time);
system.cleanup();
// 如果没有panic说明所有生命周期方法都正确工作
}
#[test]
fn test_passive_system_entity_events() {
let mut system = PassiveSystem::new("TestPassive".to_string(), None);
let mut registry = ComponentRegistry::new();
let entity = Entity::new("test_entity".to_string(), 1);
// 测试实体事件方法(都应该是安全的空操作)
system.on_entity_added(&entity);
system.on_entity_removed(&entity);
system.on_component_added(&entity, std::any::TypeId::of::<String>());
system.on_component_removed(&entity, std::any::TypeId::of::<String>());
// 如果没有panic说明所有事件处理方法都正确工作
}
#[test]
fn test_passive_system_priority_modification() {
let mut system = PassiveSystem::new("TestPassive".to_string(), None);
assert_eq!(system.get_priority(), 0);
system.set_priority(100);
assert_eq!(system.get_priority(), 100);
system.set_priority(-50);
assert_eq!(system.get_priority(), -50);
}
}

View File

@@ -0,0 +1,577 @@
use crate::core::entity_manager::EntityManager;
use crate::utils::{Matcher, QueryCondition, ComponentType};
use rustc_hash::FxHashMap;
/**
* 查询结果
*/
#[derive(serde::Serialize, serde::Deserialize)]
pub struct QueryResult {
pub entities: Vec<u32>,
pub count: usize,
pub execution_time: f64,
pub from_cache: bool,
}
/**
* 查询缓存条目
*/
struct QueryCacheEntry {
entities: Vec<u32>,
timestamp: f64,
hit_count: u32,
}
/**
* 高性能实体查询系统
* 提供快速的实体查询功能,支持按组件类型等多种方式查询实体
*/
pub struct QuerySystem {
entity_index: EntityIndex,
#[allow(dead_code)]
index_dirty: bool,
query_cache: FxHashMap<String, QueryCacheEntry>,
cache_max_size: usize,
cache_timeout: f64,
query_stats: QueryStats,
}
/**
* 实体索引结构
*/
struct EntityIndex {
by_mask: FxHashMap<String, std::collections::HashSet<u32>>,
by_tag: FxHashMap<u32, std::collections::HashSet<u32>>,
by_name: FxHashMap<String, std::collections::HashSet<u32>>,
}
/**
* 性能统计
*/
struct QueryStats {
total_queries: u32,
cache_hits: u32,
index_hits: u32,
linear_scans: u32,
}
impl QuerySystem {
pub fn new() -> Self {
Self {
entity_index: EntityIndex {
by_mask: FxHashMap::default(),
by_tag: FxHashMap::default(),
by_name: FxHashMap::default(),
},
index_dirty: true,
query_cache: FxHashMap::default(),
cache_max_size: 1000,
cache_timeout: 5000.0, // 5秒
query_stats: QueryStats {
total_queries: 0,
cache_hits: 0,
index_hits: 0,
linear_scans: 0,
},
}
}
/**
* 添加实体到查询系统
* @param entity_id 实体ID
* @param entity_manager 实体管理器引用
*/
pub fn add_entity(&mut self, entity_id: u32, entity_manager: &EntityManager) {
if let Some(_entity) = entity_manager.get_entity(entity_id) {
self.add_entity_to_indexes(entity_id, entity_manager);
self.clear_query_cache();
}
}
/**
* 从查询系统移除实体
* @param entity_id 实体ID
* @param entity_manager 实体管理器引用
*/
pub fn remove_entity(&mut self, entity_id: u32, entity_manager: &EntityManager) {
self.remove_entity_from_indexes(entity_id, entity_manager);
self.clear_query_cache();
}
/**
* 查询包含所有指定组件的实体
* @param component_mask 组件位掩码
* @param entity_manager 实体管理器引用
* @returns 查询结果,包含匹配的实体和性能信息
*/
pub fn query_all(&mut self, component_mask: u64, entity_manager: &EntityManager) -> QueryResult {
let start_time = self.get_current_time();
self.query_stats.total_queries += 1;
let cache_key = format!("all:{}", component_mask);
// 检查缓存
if let Some(cached_entities) = self.get_from_cache(&cache_key) {
self.query_stats.cache_hits += 1;
let entity_count = cached_entities.len();
return QueryResult {
entities: cached_entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: true,
};
}
// 执行查询
let entities = self.execute_mask_query(component_mask, entity_manager);
// 缓存结果
self.add_to_cache(cache_key, &entities);
let entity_count = entities.len();
QueryResult {
entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: false,
}
}
/**
* 按标签查询实体
* @param tag 要查询的标签值
* @param entity_manager 实体管理器引用
* @returns 查询结果
*/
pub fn query_by_tag(&mut self, tag: u32, entity_manager: &EntityManager) -> QueryResult {
let start_time = self.get_current_time();
self.query_stats.total_queries += 1;
let cache_key = format!("tag:{}", tag);
if let Some(cached_entities) = self.get_from_cache(&cache_key) {
self.query_stats.cache_hits += 1;
let entity_count = cached_entities.len();
return QueryResult {
entities: cached_entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: true,
};
}
let entities = entity_manager.get_entities_by_tag(tag);
self.add_to_cache(cache_key, &entities);
let entity_count = entities.len();
QueryResult {
entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: false,
}
}
/**
* 按名称查询实体
* @param name 要查询的实体名称
* @param entity_manager 实体管理器引用
* @returns 查询结果
*/
pub fn query_by_name(&mut self, name: &str, entity_manager: &EntityManager) -> QueryResult {
let start_time = self.get_current_time();
self.query_stats.total_queries += 1;
let cache_key = format!("name:{}", name);
if let Some(cached_entities) = self.get_from_cache(&cache_key) {
self.query_stats.cache_hits += 1;
let entity_count = cached_entities.len();
return QueryResult {
entities: cached_entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: true,
};
}
let entities = if let Some(entity_id) = entity_manager.get_entity_by_name(name) {
vec![entity_id]
} else {
Vec::new()
};
self.add_to_cache(cache_key, &entities);
let entity_count = entities.len();
QueryResult {
entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: false,
}
}
/**
* 执行掩码查询
*/
fn execute_mask_query(&mut self, component_mask: u64, entity_manager: &EntityManager) -> Vec<u32> {
let mut result = Vec::new();
for &entity_id in entity_manager.get_all_entity_ids().iter() {
let entity_mask = entity_manager.get_component_mask(entity_id);
if (entity_mask & component_mask) == component_mask {
result.push(entity_id);
}
}
self.query_stats.linear_scans += 1;
result
}
/**
* 将实体添加到各种索引中
*/
fn add_entity_to_indexes(&mut self, entity_id: u32, entity_manager: &EntityManager) {
if let Some(entity) = entity_manager.get_entity(entity_id) {
let mask = entity_manager.get_component_mask(entity_id);
let mask_key = mask.to_string();
self.entity_index
.by_mask
.entry(mask_key)
.or_insert_with(std::collections::HashSet::new)
.insert(entity_id);
self.entity_index
.by_tag
.entry(entity.tag())
.or_insert_with(std::collections::HashSet::new)
.insert(entity_id);
self.entity_index
.by_name
.entry(entity.name.clone())
.or_insert_with(std::collections::HashSet::new)
.insert(entity_id);
}
}
/**
* 从各种索引中移除实体
*/
fn remove_entity_from_indexes(&mut self, entity_id: u32, entity_manager: &EntityManager) {
if let Some(entity) = entity_manager.get_entity(entity_id) {
let mask = entity_manager.get_component_mask(entity_id);
let mask_key = mask.to_string();
if let Some(mask_set) = self.entity_index.by_mask.get_mut(&mask_key) {
mask_set.remove(&entity_id);
if mask_set.is_empty() {
self.entity_index.by_mask.remove(&mask_key);
}
}
if let Some(tag_set) = self.entity_index.by_tag.get_mut(&entity.tag()) {
tag_set.remove(&entity_id);
if tag_set.is_empty() {
self.entity_index.by_tag.remove(&entity.tag());
}
}
if let Some(name_set) = self.entity_index.by_name.get_mut(&entity.name) {
name_set.remove(&entity_id);
if name_set.is_empty() {
self.entity_index.by_name.remove(&entity.name);
}
}
}
}
/**
* 从缓存获取查询结果
*/
fn get_from_cache(&mut self, cache_key: &str) -> Option<Vec<u32>> {
let current_time = self.get_current_time();
if let Some(entry) = self.query_cache.get_mut(cache_key) {
if current_time - entry.timestamp <= self.cache_timeout {
entry.hit_count += 1;
return Some(entry.entities.clone());
} else {
self.query_cache.remove(cache_key);
}
}
None
}
/**
* 添加查询结果到缓存
*/
fn add_to_cache(&mut self, cache_key: String, entities: &[u32]) {
if self.query_cache.len() >= self.cache_max_size {
self.cleanup_cache();
}
self.query_cache.insert(cache_key, QueryCacheEntry {
entities: entities.to_vec(),
timestamp: self.get_current_time(),
hit_count: 0,
});
}
/**
* 清理缓存
*/
fn cleanup_cache(&mut self) {
let current_time = self.get_current_time();
// 移除过期的缓存条目
self.query_cache.retain(|_, entry| {
current_time - entry.timestamp <= self.cache_timeout
});
// 如果还是太满,移除最少使用的条目
if self.query_cache.len() >= self.cache_max_size {
let entries: Vec<_> = self.query_cache.iter().map(|(k, v)| (k.clone(), v.hit_count)).collect();
let mut sorted_entries = entries;
sorted_entries.sort_by_key(|(_, hit_count)| *hit_count);
let to_remove = (self.cache_max_size as f32 * 0.2) as usize;
for (key, _) in sorted_entries.into_iter().take(to_remove) {
self.query_cache.remove(&key);
}
}
}
/**
* 清除所有查询缓存
*/
fn clear_query_cache(&mut self) {
self.query_cache.clear();
}
/**
* 获取当前时间戳(毫秒)
*/
fn get_current_time(&self) -> f64 {
// 在WASM环境中这将使用js-sys获取时间
// 这里使用简化实现转换为f64毫秒
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as f64
}
/**
* 获取系统统计信息
*/
/**
* 清空查询缓存
*/
pub fn clear_cache(&mut self) {
self.query_cache.clear();
}
/**
* 基于Matcher的高级查询
*
* 使用Matcher描述复杂查询条件支持all/any/none组合查询
*/
pub fn query_with_matcher(&mut self, matcher: &Matcher, entity_manager: &EntityManager) -> QueryResult {
let start_time = self.get_current_time();
// 生成查询缓存键
let cache_key = self.generate_matcher_cache_key(matcher);
// 检查缓存
if let Some(cached_result) = self.get_from_cache(&cache_key) {
let count = cached_result.len();
return QueryResult {
entities: cached_result,
count,
execution_time: self.get_current_time() - start_time,
from_cache: true,
};
}
// 执行查询
let entities = self.execute_matcher_query(matcher, entity_manager);
// 添加到缓存
self.add_to_cache(cache_key, &entities);
let entity_count = entities.len();
QueryResult {
entities,
count: entity_count,
execution_time: self.get_current_time() - start_time,
from_cache: false,
}
}
/**
* 执行Matcher查询的核心逻辑
*/
fn execute_matcher_query(&mut self, matcher: &Matcher, entity_manager: &EntityManager) -> Vec<u32> {
let condition = matcher.get_condition();
let all_entity_ids = entity_manager.get_all_entity_ids();
let mut matching_entities = Vec::new();
// 遍历所有实体进行匹配
for &entity_id in &all_entity_ids {
if self.entity_matches_condition(entity_id, condition, entity_manager) {
matching_entities.push(entity_id);
}
}
self.query_stats.linear_scans += 1;
matching_entities
}
/**
* 检查实体是否匹配查询条件
*/
fn entity_matches_condition(&self, entity_id: u32, condition: &QueryCondition, entity_manager: &EntityManager) -> bool {
let entity = match entity_manager.get_entity(entity_id) {
Some(entity) => entity,
None => return false,
};
// 检查名称条件
if let Some(ref name) = condition.name {
if &entity.name != name {
return false;
}
}
// 检查标签条件
if let Some(tag) = condition.tag {
if entity.tag() != tag {
return false;
}
}
// 检查单组件条件
if let Some(component_type) = condition.component {
if !self.entity_has_component_type(entity_id, component_type, entity_manager) {
return false;
}
}
// 检查all条件必须包含所有指定组件
if !condition.all.is_empty() {
for &component_type in &condition.all {
if !self.entity_has_component_type(entity_id, component_type, entity_manager) {
return false;
}
}
}
// 检查any条件必须包含至少一个指定组件
if !condition.any.is_empty() {
let has_any = condition.any.iter()
.any(|&component_type| self.entity_has_component_type(entity_id, component_type, entity_manager));
if !has_any {
return false;
}
}
// 检查none条件不能包含任何指定组件
if !condition.none.is_empty() {
for &component_type in &condition.none {
if self.entity_has_component_type(entity_id, component_type, entity_manager) {
return false;
}
}
}
true
}
/**
* 检查实体是否有指定类型的组件
* 这里需要EntityManager提供按TypeId查询组件的功能
*/
fn entity_has_component_type(&self, entity_id: u32, component_type: ComponentType, _entity_manager: &EntityManager) -> bool {
// TODO: 这里需要EntityManager支持按TypeId查询组件
// 目前先返回false作为占位实现
// 实际实现需要EntityManager提供get_component_by_type_id方法
let _ = (entity_id, component_type);
false
}
/**
* 为Matcher生成缓存键
*/
fn generate_matcher_cache_key(&self, matcher: &Matcher) -> String {
let condition = matcher.get_condition();
let mut key_parts = Vec::new();
// 添加各种条件到键中
if !condition.all.is_empty() {
let type_ids: Vec<String> = condition.all.iter()
.map(|t| format!("{:?}", t))
.collect();
key_parts.push(format!("all:{}", type_ids.join(",")));
}
if !condition.any.is_empty() {
let type_ids: Vec<String> = condition.any.iter()
.map(|t| format!("{:?}", t))
.collect();
key_parts.push(format!("any:{}", type_ids.join(",")));
}
if !condition.none.is_empty() {
let type_ids: Vec<String> = condition.none.iter()
.map(|t| format!("{:?}", t))
.collect();
key_parts.push(format!("none:{}", type_ids.join(",")));
}
if let Some(tag) = condition.tag {
key_parts.push(format!("tag:{}", tag));
}
if let Some(ref name) = condition.name {
key_parts.push(format!("name:{}", name));
}
if let Some(component) = condition.component {
key_parts.push(format!("comp:{:?}", component));
}
format!("matcher:{}", key_parts.join("|"))
}
pub fn get_stats(&self) -> QuerySystemStats {
let cache_hit_rate = if self.query_stats.total_queries > 0 {
(self.query_stats.cache_hits as f32 / self.query_stats.total_queries as f32) * 100.0
} else {
0.0
};
QuerySystemStats {
total_queries: self.query_stats.total_queries,
cache_hits: self.query_stats.cache_hits,
index_hits: self.query_stats.index_hits,
linear_scans: self.query_stats.linear_scans,
cache_hit_rate,
cache_size: self.query_cache.len(),
}
}
}
/**
* 查询系统统计信息
*/
#[derive(serde::Serialize, serde::Deserialize)]
pub struct QuerySystemStats {
pub total_queries: u32,
pub cache_hits: u32,
pub index_hits: u32,
pub linear_scans: u32,
pub cache_hit_rate: f32,
pub cache_size: usize,
}

View File

@@ -0,0 +1,403 @@
use crate::core::entity_manager::EntityManager;
use crate::core::query_system::QuerySystem;
use crate::core::systems::{System, SystemManager, SystemContext};
use crate::storage::component_storage::ComponentStorageManager;
use crate::utils::time::Time;
/**
* 场景管理器
*
* Scene是ECS系统中的顶层容器管理所有实体、组件和系统
* 提供统一的实体管理、组件存储和查询功能
*/
pub struct Scene {
/// 场景名称
name: String,
/// 是否激活状态
active: bool,
/// 实体管理器
entity_manager: EntityManager,
/// 组件存储管理器
component_storage_manager: ComponentStorageManager,
/// 查询系统
query_system: QuerySystem,
/// 系统管理器
system_manager: SystemManager,
/// 场景统计信息
stats: SceneStats,
}
impl Scene {
/**
* 创建新场景
*/
pub fn new() -> Self {
Self {
name: String::new(),
active: true,
entity_manager: EntityManager::new(),
component_storage_manager: ComponentStorageManager::new(),
query_system: QuerySystem::new(),
system_manager: SystemManager::new(),
stats: SceneStats::default(),
}
}
/**
* 创建带名称的新场景
*/
pub fn new_with_name(name: String) -> Self {
Self {
name,
active: true,
entity_manager: EntityManager::new(),
component_storage_manager: ComponentStorageManager::new(),
query_system: QuerySystem::new(),
system_manager: SystemManager::new(),
stats: SceneStats::default(),
}
}
// ========== 场景属性 ==========
/**
* 获取场景名称
*/
pub fn name(&self) -> &str {
&self.name
}
/**
* 设置场景名称
*/
pub fn set_name(&mut self, name: String) {
self.name = name;
}
/**
* 获取激活状态
*/
pub fn active(&self) -> bool {
self.active
}
/**
* 设置激活状态
*/
pub fn set_active(&mut self, active: bool) {
self.active = active;
}
// ========== 实体管理 ==========
/**
* 创建实体
*/
pub fn create_entity(&mut self, name: Option<String>) -> u32 {
let entity_id = self.entity_manager.create_entity(name);
self.stats.total_entities_created += 1;
entity_id
}
/**
* 批量创建实体
*/
pub fn create_entities_batch(&mut self, count: u32, name_prefix: Option<String>) -> Vec<u32> {
let entities = self.entity_manager.create_entities_batch(count, name_prefix);
self.stats.total_entities_created += count as u64;
entities
}
/**
* 销毁实体
*/
pub fn destroy_entity(&mut self, entity_id: u32) -> bool {
if self.entity_manager.destroy_entity(entity_id) {
// 清理组件存储
self.component_storage_manager.remove_all_components(entity_id);
self.stats.total_entities_destroyed += 1;
true
} else {
false
}
}
/**
* 获取实体管理器引用
*/
pub fn entity_manager(&self) -> &EntityManager {
&self.entity_manager
}
/**
* 获取实体管理器可变引用
*/
pub fn entity_manager_mut(&mut self) -> &mut EntityManager {
&mut self.entity_manager
}
// ========== 组件管理 ==========
/**
* 获取组件存储管理器引用
*/
pub fn component_storage_manager(&self) -> &ComponentStorageManager {
&self.component_storage_manager
}
/**
* 获取组件存储管理器可变引用
*/
pub fn component_storage_manager_mut(&mut self) -> &mut ComponentStorageManager {
&mut self.component_storage_manager
}
// ========== 查询系统 ==========
/**
* 获取查询系统引用
*/
pub fn query_system(&self) -> &QuerySystem {
&self.query_system
}
/**
* 获取查询系统可变引用
*/
pub fn query_system_mut(&mut self) -> &mut QuerySystem {
&mut self.query_system
}
// ========== 系统管理 ==========
/**
* 添加系统
*/
pub fn add_system<T: System + 'static>(&mut self, system: T) {
self.system_manager.add_system(system);
}
/**
* 移除系统
*/
pub fn remove_system<T: System + 'static>(&mut self) -> bool {
self.system_manager.remove_system::<T>()
}
/**
* 获取系统
*/
pub fn get_system<T: System + 'static>(&self) -> Option<&T> {
self.system_manager.get_system::<T>()
}
/**
* 获取可变系统
*/
pub fn get_system_mut<T: System + 'static>(&mut self) -> Option<&mut T> {
self.system_manager.get_system_mut::<T>()
}
/**
* 获取系统管理器引用
*/
pub fn system_manager(&self) -> &SystemManager {
&self.system_manager
}
/**
* 获取系统管理器可变引用
*/
pub fn system_manager_mut(&mut self) -> &mut SystemManager {
&mut self.system_manager
}
// ========== 场景生命周期 ==========
/**
* 初始化场景
*/
pub fn initialize(&mut self) {
// 创建系统上下文并初始化系统管理器
let mut context = SystemContext {
entity_manager: &mut self.entity_manager,
component_storage_manager: &mut self.component_storage_manager,
};
self.system_manager.initialize(&mut context);
}
/**
* 更新场景
*/
pub fn update(&mut self, delta_time: f64) {
if !self.active {
return;
}
// 更新时间
Time::update(delta_time);
// 创建系统上下文
let mut context = SystemContext {
entity_manager: &mut self.entity_manager,
component_storage_manager: &mut self.component_storage_manager,
};
// 更新所有系统
self.system_manager.update(&mut context);
// 重新创建系统上下文(避免借用检查问题)
let mut context = SystemContext {
entity_manager: &mut self.entity_manager,
component_storage_manager: &mut self.component_storage_manager,
};
// 后更新系统
self.system_manager.late_update(&mut context);
// 更新所有激活的实体(在系统更新完成后)
let active_entities = self.entity_manager.get_all_entity_ids();
for entity_id in active_entities {
if let Some(entity) = self.entity_manager.get_entity_mut(entity_id) {
entity.update();
}
}
self.stats.total_updates += 1;
}
/**
* 清空场景
*/
pub fn clear(&mut self) {
// 创建系统上下文并清理系统
let mut context = SystemContext {
entity_manager: &mut self.entity_manager,
component_storage_manager: &mut self.component_storage_manager,
};
self.system_manager.cleanup(&mut context);
self.entity_manager = EntityManager::new();
self.component_storage_manager.clear();
self.query_system.clear_cache();
self.system_manager = SystemManager::new();
self.stats = SceneStats::default();
}
// ========== 统计信息 ==========
/**
* 获取场景统计信息
*/
pub fn get_stats(&self) -> &SceneStats {
&self.stats
}
/**
* 获取实体数量
*/
pub fn entity_count(&self) -> usize {
self.entity_manager.entity_count()
}
/**
* 获取激活实体数量
*/
pub fn active_entity_count(&self) -> usize {
self.entity_manager.active_entity_count()
}
/**
* 获取调试信息
*/
pub fn get_debug_info(&self) -> String {
format!(
"{{\"name\":\"{}\",\"active\":{},\"entity_count\":{},\"active_entity_count\":{},\"total_entities_created\":{},\"total_entities_destroyed\":{},\"total_updates\":{}}}",
self.name,
self.active,
self.entity_count(),
self.active_entity_count(),
self.stats.total_entities_created,
self.stats.total_entities_destroyed,
self.stats.total_updates
)
}
// ========== SceneBuilder支持方法 ==========
/**
* 添加实体到场景
*/
pub fn add_entity(&mut self, entity: crate::core::Entity) {
self.entity_manager.add_entity(entity);
self.stats.total_entities_created += 1;
}
/**
* 添加系统到场景Box版本
*/
pub fn add_system_boxed(&mut self, system: Box<dyn System>) {
self.system_manager.add_system_boxed(system);
}
/**
* 获取系统数量
*/
pub fn system_count(&self) -> usize {
self.system_manager.system_count()
}
/**
* 设置启用状态
*/
pub fn set_enabled(&mut self, enabled: bool) {
self.active = enabled;
}
/**
* 检查是否启用
*/
pub fn is_enabled(&self) -> bool {
self.active
}
/**
* 预留容量
*/
pub fn reserve_capacity(&mut self, entity_capacity: usize, system_capacity: usize) {
self.entity_manager.reserve_capacity(entity_capacity);
self.system_manager.reserve_capacity(system_capacity);
}
}
/**
* 场景统计信息
*/
#[derive(Default)]
pub struct SceneStats {
/// 创建的实体总数
pub total_entities_created: u64,
/// 销毁的实体总数
pub total_entities_destroyed: u64,
/// 更新总次数
pub total_updates: u64,
}
impl std::fmt::Debug for Scene {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Scene")
.field("name", &self.name)
.field("active", &self.active)
.field("entity_count", &self.entity_count())
.field("active_entity_count", &self.active_entity_count())
.finish()
}
}

View File

@@ -0,0 +1,598 @@
use crate::core::{Scene, Entity, System};
use crate::core::fluent_api::EntityBuilder;
/**
* 场景构建器
* 提供流式API创建和配置场景
*/
pub struct SceneBuilder {
scene: Scene,
}
impl SceneBuilder {
/**
* 创建场景构建器
*/
pub fn new() -> Self {
Self {
scene: Scene::new(),
}
}
/**
* 设置场景名称
*/
pub fn named(mut self, name: &str) -> Self {
self.scene.set_name(name.to_string());
self
}
/**
* 设置场景是否启用
*/
pub fn enabled(mut self, enabled: bool) -> Self {
self.scene.set_enabled(enabled);
self
}
/**
* 添加实体
*/
pub fn with_entity(mut self, entity: Entity) -> Self {
self.scene.add_entity(entity);
self
}
/**
* 批量添加实体
*/
pub fn with_entities(mut self, entities: Vec<Entity>) -> Self {
for entity in entities {
self.scene.add_entity(entity);
}
self
}
/**
* 使用实体构建器添加实体
*/
pub fn with_entity_builder<F>(mut self, builder_fn: F) -> Self
where
F: FnOnce(EntityBuilder) -> EntityBuilder,
{
let builder = EntityBuilder::new("", 0);
let configured_builder = builder_fn(builder);
let entity = configured_builder.build();
self.scene.add_entity(entity);
self
}
/**
* 批量使用实体构建器添加实体
*/
pub fn with_entity_builders<F>(mut self, count: usize, builder_fn: F) -> Self
where
F: Fn(usize, EntityBuilder) -> EntityBuilder,
{
for i in 0..count {
let builder = EntityBuilder::new("", 0);
let configured_builder = builder_fn(i, builder);
let entity = configured_builder.build();
self.scene.add_entity(entity);
}
self
}
/**
* 添加系统
*/
pub fn with_system(mut self, system: Box<dyn System>) -> Self {
self.scene.add_system_boxed(system);
self
}
/**
* 批量添加系统
*/
pub fn with_systems(mut self, systems: Vec<Box<dyn System>>) -> Self {
for system in systems {
self.scene.add_system_boxed(system);
}
self
}
/**
* 条件性添加实体
*/
pub fn with_entity_if(mut self, condition: bool, entity: Entity) -> Self {
if condition {
self.scene.add_entity(entity);
}
self
}
/**
* 条件性添加系统
*/
pub fn with_system_if(mut self, condition: bool, system: Box<dyn System>) -> Self {
if condition {
self.scene.add_system_boxed(system);
}
self
}
/**
* 使用配置函数配置场景
*/
pub fn configure<F>(mut self, configurator: F) -> Self
where
F: FnOnce(&mut Scene),
{
configurator(&mut self.scene);
self
}
/**
* 条件性配置场景
*/
pub fn configure_if<F>(mut self, condition: bool, configurator: F) -> Self
where
F: FnOnce(&mut Scene),
{
if condition {
configurator(&mut self.scene);
}
self
}
/**
* 批量创建简单实体
*/
pub fn with_simple_entities(mut self, count: usize, name_prefix: &str) -> Self {
for i in 0..count {
let mut entity = Entity::new(0); // ID将由EntityManager分配
entity.set_name(format!("{}{}", name_prefix, i));
self.scene.add_entity(entity);
}
self
}
/**
* 使用预定义场景模板
*/
pub fn from_template(self, template: SceneTemplate) -> Self {
match template {
SceneTemplate::Empty => self,
SceneTemplate::Basic => {
self.named("Basic Scene")
.enabled(true)
.with_simple_entities(10, "Entity_")
},
SceneTemplate::Testing => {
self.named("Test Scene")
.enabled(true)
.with_simple_entities(5, "TestEntity_")
},
}
}
/**
* 设置场景容量预估
*/
pub fn with_capacity(mut self, entity_capacity: usize, system_capacity: usize) -> Self {
self.scene.reserve_capacity(entity_capacity, system_capacity);
self
}
/**
* 验证场景配置
*/
pub fn validate(self) -> Result<Self, String> {
// 基本验证
if self.scene.name().is_empty() {
return Err("Scene name cannot be empty".to_string());
}
if self.scene.entity_count() == 0 {
return Err("Scene must have at least one entity".to_string());
}
Ok(self)
}
/**
* 构建并返回场景
*/
pub fn build(self) -> Scene {
self.scene
}
/**
* 验证并构建场景
*/
pub fn validate_and_build(self) -> Result<Scene, String> {
self.validate().map(|builder| builder.build())
}
/**
* 获取当前场景的统计信息
*/
pub fn get_stats(&self) -> SceneBuilderStats {
SceneBuilderStats {
entity_count: self.scene.entity_count(),
system_count: self.scene.system_count(),
is_enabled: self.scene.is_enabled(),
name_length: self.scene.name().len(),
}
}
}
/**
* 场景模板枚举
* 提供预定义的场景配置
*/
#[derive(Debug, Clone)]
pub enum SceneTemplate {
Empty,
Basic,
Testing,
}
/**
* 场景构建器统计信息
*/
#[derive(Debug, Clone)]
pub struct SceneBuilderStats {
pub entity_count: usize,
pub system_count: usize,
pub is_enabled: bool,
pub name_length: usize,
}
impl SceneBuilderStats {
/**
* 检查场景是否为空
*/
pub fn is_empty(&self) -> bool {
self.entity_count == 0 && self.system_count == 0
}
/**
* 检查场景是否已配置
*/
pub fn is_configured(&self) -> bool {
self.entity_count > 0 || self.system_count > 0
}
/**
* 获取场景复杂度评分
*/
pub fn complexity_score(&self) -> f64 {
(self.entity_count as f64 * 1.0) + (self.system_count as f64 * 2.0)
}
}
/**
* 场景构建器工厂
* 提供创建各种场景构建器的便捷方法
*/
pub struct SceneBuilderFactory;
impl SceneBuilderFactory {
/**
* 创建空场景构建器
*/
pub fn empty() -> SceneBuilder {
SceneBuilder::new()
}
/**
* 创建基础场景构建器
*/
pub fn basic(name: &str) -> SceneBuilder {
SceneBuilder::new()
.named(name)
.enabled(true)
}
/**
* 创建测试场景构建器
*/
pub fn for_testing() -> SceneBuilder {
SceneBuilder::new()
.from_template(SceneTemplate::Testing)
}
/**
* 创建指定容量的场景构建器
*/
pub fn with_capacity(entity_capacity: usize, system_capacity: usize) -> SceneBuilder {
SceneBuilder::new()
.with_capacity(entity_capacity, system_capacity)
}
/**
* 从模板创建场景构建器
*/
pub fn from_template(template: SceneTemplate) -> SceneBuilder {
SceneBuilder::new().from_template(template)
}
}
/**
* 场景构建器管理器
* 管理多个场景构建器的全局统计
*/
#[derive(Debug)]
pub struct SceneBuilderManager {
total_scenes_built: u64,
total_entities_created: u64,
total_systems_added: u64,
validation_failures: u64,
}
impl SceneBuilderManager {
pub fn new() -> Self {
Self {
total_scenes_built: 0,
total_entities_created: 0,
total_systems_added: 0,
validation_failures: 0,
}
}
/**
* 记录场景构建
*/
pub fn record_scene_built(&mut self, stats: &SceneBuilderStats) {
self.total_scenes_built += 1;
self.total_entities_created += stats.entity_count as u64;
self.total_systems_added += stats.system_count as u64;
}
/**
* 记录验证失败
*/
pub fn record_validation_failure(&mut self) {
self.validation_failures += 1;
}
/**
* 重置统计信息
*/
pub fn reset(&mut self) {
self.total_scenes_built = 0;
self.total_entities_created = 0;
self.total_systems_added = 0;
self.validation_failures = 0;
}
/**
* 获取平均每个场景的实体数
*/
pub fn average_entities_per_scene(&self) -> f64 {
if self.total_scenes_built == 0 {
0.0
} else {
self.total_entities_created as f64 / self.total_scenes_built as f64
}
}
/**
* 获取平均每个场景的系统数
*/
pub fn average_systems_per_scene(&self) -> f64 {
if self.total_scenes_built == 0 {
0.0
} else {
self.total_systems_added as f64 / self.total_scenes_built as f64
}
}
/**
* 获取构建成功率
*/
pub fn success_rate(&self) -> f64 {
let total_attempts = self.total_scenes_built + self.validation_failures;
if total_attempts == 0 {
1.0
} else {
self.total_scenes_built as f64 / total_attempts as f64
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::Any;
use crate::core::systems::SystemContext;
// 测试用的简单系统
struct TestSystem {
enabled: bool,
update_order: i32,
}
impl TestSystem {
fn new() -> Self {
Self {
enabled: true,
update_order: 0,
}
}
}
impl System for TestSystem {
fn initialize(&mut self, _context: &mut SystemContext) {}
fn update(&mut self, _context: &mut SystemContext) {}
fn late_update(&mut self, _context: &mut SystemContext) {}
fn cleanup(&mut self, _context: &mut SystemContext) {}
fn enabled(&self) -> bool { self.enabled }
fn set_enabled(&mut self, enabled: bool) { self.enabled = enabled; }
fn name(&self) -> &str { "TestSystem" }
fn update_order(&self) -> i32 { self.update_order }
fn set_update_order(&mut self, order: i32) { self.update_order = order; }
fn as_any(&self) -> &dyn Any { self }
fn as_any_mut(&mut self) -> &mut dyn Any { self }
}
#[test]
fn test_scene_builder_basic() {
let scene = SceneBuilder::new()
.named("Test Scene")
.enabled(true)
.build();
assert_eq!(scene.name(), "Test Scene");
assert!(scene.enabled());
}
#[test]
fn test_scene_builder_with_entities() {
let entity1 = Entity::new(1);
let entity2 = Entity::new(2);
let scene = SceneBuilder::new()
.with_entity(entity1)
.with_entity(entity2)
.build();
assert_eq!(scene.entity_count(), 2);
}
#[test]
fn test_scene_builder_with_simple_entities() {
let scene = SceneBuilder::new()
.with_simple_entities(5, "Entity_")
.build();
assert_eq!(scene.entity_count(), 5);
}
#[test]
fn test_scene_builder_with_systems() {
let system = Box::new(TestSystem::new());
let scene = SceneBuilder::new()
.with_system(system)
.build();
assert_eq!(scene.system_count(), 1);
}
#[test]
fn test_scene_builder_conditional() {
let entity = Entity::new(1);
let system = Box::new(TestSystem::new());
let scene = SceneBuilder::new()
.with_entity_if(true, entity)
.with_system_if(false, system)
.build();
assert_eq!(scene.entity_count(), 1);
assert_eq!(scene.system_count(), 0);
}
#[test]
fn test_scene_builder_configure() {
let scene = SceneBuilder::new()
.configure(|scene| {
scene.set_name("Configured Scene".to_string());
})
.build();
assert_eq!(scene.name(), "Configured Scene");
}
#[test]
fn test_scene_builder_from_template() {
let scene = SceneBuilder::new()
.from_template(SceneTemplate::Basic)
.build();
assert_eq!(scene.name(), "Basic Scene");
assert_eq!(scene.entity_count(), 10);
}
#[test]
fn test_scene_builder_validation() {
// 验证失败 - 空名称
let result1 = SceneBuilder::new()
.validate_and_build();
assert!(result1.is_err());
// 验证失败 - 无实体
let result2 = SceneBuilder::new()
.named("Test")
.validate_and_build();
assert!(result2.is_err());
// 验证成功
let result3 = SceneBuilder::new()
.named("Test")
.with_simple_entities(1, "Entity_")
.validate_and_build();
assert!(result3.is_ok());
}
#[test]
fn test_scene_builder_stats() {
let builder = SceneBuilder::new()
.named("Test Scene")
.with_simple_entities(3, "Entity_")
.with_system(Box::new(TestSystem::new()));
let stats = builder.get_stats();
assert_eq!(stats.entity_count, 3);
assert_eq!(stats.system_count, 1);
assert!(!stats.is_empty());
assert!(stats.is_configured());
assert_eq!(stats.complexity_score(), 5.0); // 3*1 + 1*2
}
#[test]
fn test_scene_builder_factory() {
let empty_scene = SceneBuilderFactory::empty().build();
assert_eq!(empty_scene.entity_count(), 0);
let basic_scene = SceneBuilderFactory::basic("Test").build();
assert_eq!(basic_scene.name(), "Test");
let test_scene = SceneBuilderFactory::for_testing().build();
assert_eq!(test_scene.name(), "Test Scene");
assert_eq!(test_scene.entity_count(), 5);
}
#[test]
fn test_scene_builder_manager() {
let mut manager = SceneBuilderManager::new();
let stats1 = SceneBuilderStats {
entity_count: 5,
system_count: 2,
is_enabled: true,
name_length: 10,
};
let stats2 = SceneBuilderStats {
entity_count: 3,
system_count: 1,
is_enabled: true,
name_length: 8,
};
manager.record_scene_built(&stats1);
manager.record_scene_built(&stats2);
manager.record_validation_failure();
assert_eq!(manager.total_scenes_built, 2);
assert_eq!(manager.total_entities_created, 8);
assert_eq!(manager.total_systems_added, 3);
assert_eq!(manager.validation_failures, 1);
assert_eq!(manager.average_entities_per_scene(), 4.0);
assert_eq!(manager.average_systems_per_scene(), 1.5);
assert!((manager.success_rate() - 0.6666666666666666).abs() < 0.0001);
}
}

View File

@@ -0,0 +1,521 @@
use crate::core::entity::Entity;
use crate::core::entity_manager::EntityManager;
use crate::storage::component_storage::ComponentStorageManager;
use crate::utils::time::Time;
use std::any::Any;
/**
* 系统上下文
* 提供系统执行时需要的各种管理器引用
*/
pub struct SystemContext<'a> {
pub entity_manager: &'a mut EntityManager,
pub component_storage_manager: &'a mut ComponentStorageManager,
}
/**
* 系统基础trait
* 定义ECS系统的基本接口
*/
pub trait System: Send + Sync {
/**
* 系统初始化
*/
#[allow(unused_variables)]
fn initialize(&mut self, context: &mut SystemContext) {
// 默认空实现
}
/**
* 系统更新
*/
fn update(&mut self, context: &mut SystemContext);
/**
* 系统后更新在所有update完成后调用
*/
#[allow(unused_variables)]
fn late_update(&mut self, context: &mut SystemContext) {
// 默认空实现
}
/**
* 系统销毁清理
*/
#[allow(unused_variables)]
fn cleanup(&mut self, context: &mut SystemContext) {
// 默认空实现
}
/**
* 获取系统更新顺序
*/
fn update_order(&self) -> i32 {
0
}
/**
* 设置系统更新顺序
*/
fn set_update_order(&mut self, order: i32);
/**
* 获取系统启用状态
*/
fn enabled(&self) -> bool {
true
}
/**
* 设置系统启用状态
*/
fn set_enabled(&mut self, enabled: bool);
/**
* 获取系统名称
*/
fn name(&self) -> &str {
"System"
}
/**
* 转换为Any以支持动态转换
*/
fn as_any(&self) -> &dyn Any;
/**
* 转换为可变Any以支持动态转换
*/
fn as_any_mut(&mut self) -> &mut dyn Any;
}
/**
* 实体系统基类
* 用于处理一组符合特定条件的实体
*/
pub struct EntitySystem {
update_order: i32,
enabled: bool,
name: String,
initialized: bool,
}
impl EntitySystem {
pub fn new(name: String) -> Self {
Self {
update_order: 0,
enabled: true,
name,
initialized: false,
}
}
/**
* 检查是否需要处理
*/
pub fn check_processing(&self) -> bool {
self.enabled
}
/**
* 处理实体列表
*/
pub fn process(&mut self, entities: &[&Entity], context: &mut SystemContext) {
if !self.check_processing() {
return;
}
self.process_entities(entities, context);
}
/**
* 处理实体的具体实现(由子类重写)
*/
#[allow(unused_variables)]
pub fn process_entities(&mut self, entities: &[&Entity], context: &mut SystemContext) {
// 默认空实现
}
/**
* 根据实体ID列表处理实体
* 子类可以重写这个方法实现自定义的实体处理逻辑
*/
#[allow(unused_variables)]
pub fn process_entity_ids(&mut self, entity_ids: &[u32], context: &mut SystemContext) {
// 默认空实现,由子类根据需要重写
// 这样避免了借用检查问题,因为子类可以自己决定如何访问实体
}
/**
* 处理单个实体(由子类重写)
*/
#[allow(unused_variables)]
pub fn process_single_entity(&mut self, entity: &Entity, context: &mut SystemContext) {
// 默认空实现
}
/**
* 系统初始化回调
*/
#[allow(unused_variables)]
pub fn on_initialize(&mut self, context: &mut SystemContext) {
// 默认空实现
}
/**
* 实体添加到系统时的回调
*/
#[allow(unused_variables)]
pub fn on_entity_added(&mut self, entity: &Entity, context: &mut SystemContext) {
// 默认空实现
}
/**
* 实体从系统移除时的回调
*/
#[allow(unused_variables)]
pub fn on_entity_removed(&mut self, entity: &Entity, context: &mut SystemContext) {
// 默认空实现
}
}
impl System for EntitySystem {
fn initialize(&mut self, context: &mut SystemContext) {
if !self.initialized {
self.on_initialize(context);
self.initialized = true;
}
}
fn update(&mut self, context: &mut SystemContext) {
if !self.enabled {
return;
}
// 先获取所有实体ID
let entity_ids = context.entity_manager.get_all_entity_ids();
// 然后直接处理,避免同时持有不可变和可变引用
self.process_entity_ids(&entity_ids, context);
}
fn set_update_order(&mut self, order: i32) {
self.update_order = order;
}
fn update_order(&self) -> i32 {
self.update_order
}
fn enabled(&self) -> bool {
self.enabled
}
fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
fn name(&self) -> &str {
&self.name
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 处理系统
* 每帧调用processSystem方法
*/
pub struct ProcessingSystem {
base: EntitySystem,
}
impl ProcessingSystem {
pub fn new(name: String) -> Self {
Self {
base: EntitySystem::new(name),
}
}
/**
* 处理系统的具体方法,由子类实现
*/
#[allow(unused_variables)]
pub fn process_system(&mut self, context: &mut SystemContext) {
// 默认空实现,由子类重写
}
}
impl System for ProcessingSystem {
fn initialize(&mut self, context: &mut SystemContext) {
self.base.initialize(context);
}
fn update(&mut self, context: &mut SystemContext) {
if self.base.enabled() {
self.process_system(context);
}
}
fn set_update_order(&mut self, order: i32) {
self.base.set_update_order(order);
}
fn update_order(&self) -> i32 {
self.base.update_order()
}
fn enabled(&self) -> bool {
self.base.enabled()
}
fn set_enabled(&mut self, enabled: bool) {
self.base.set_enabled(enabled);
}
fn name(&self) -> &str {
self.base.name()
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 间隔系统
* 按指定时间间隔执行处理
*/
pub struct IntervalSystem {
base: EntitySystem,
interval: f64,
accumulator: f64,
}
impl IntervalSystem {
pub fn new(name: String, interval: f64) -> Self {
Self {
base: EntitySystem::new(name),
interval,
accumulator: 0.0,
}
}
/**
* 检查是否应该处理
*/
fn should_process(&mut self) -> bool {
if !self.base.enabled() {
return false;
}
self.accumulator += Time::delta_time();
if self.accumulator >= self.interval {
self.accumulator -= self.interval;
true
} else {
false
}
}
/**
* 间隔处理方法,由子类实现
*/
#[allow(unused_variables)]
pub fn process_interval(&mut self, context: &mut SystemContext) {
// 默认空实现,由子类重写
}
}
impl System for IntervalSystem {
fn initialize(&mut self, context: &mut SystemContext) {
self.base.initialize(context);
}
fn update(&mut self, context: &mut SystemContext) {
if self.should_process() {
self.process_interval(context);
}
}
fn set_update_order(&mut self, order: i32) {
self.base.set_update_order(order);
}
fn update_order(&self) -> i32 {
self.base.update_order()
}
fn enabled(&self) -> bool {
self.base.enabled()
}
fn set_enabled(&mut self, enabled: bool) {
self.base.set_enabled(enabled);
}
fn name(&self) -> &str {
self.base.name()
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 系统管理器
* 管理所有系统的注册、更新和生命周期
*/
pub struct SystemManager {
systems: Vec<Box<dyn System>>,
initialized: bool,
}
impl SystemManager {
pub fn new() -> Self {
Self {
systems: Vec::new(),
initialized: false,
}
}
/**
* 添加系统
*/
pub fn add_system<T: System + 'static>(&mut self, system: T) {
self.systems.push(Box::new(system));
// 按更新顺序排序
self.systems.sort_by_key(|s| s.update_order());
}
/**
* 添加系统Box版本
*/
pub fn add_system_boxed(&mut self, system: Box<dyn System>) {
self.systems.push(system);
// 按更新顺序排序
self.systems.sort_by_key(|s| s.update_order());
}
/**
* 移除系统
*/
pub fn remove_system<T: System + 'static>(&mut self) -> bool {
let initial_len = self.systems.len();
self.systems.retain(|system| {
!system.as_any().is::<T>()
});
initial_len != self.systems.len()
}
/**
* 获取系统
*/
pub fn get_system<T: System + 'static>(&self) -> Option<&T> {
for system in &self.systems {
if let Some(s) = system.as_any().downcast_ref::<T>() {
return Some(s);
}
}
None
}
/**
* 获取可变系统
*/
pub fn get_system_mut<T: System + 'static>(&mut self) -> Option<&mut T> {
for system in &mut self.systems {
if let Some(s) = system.as_any_mut().downcast_mut::<T>() {
return Some(s);
}
}
None
}
/**
* 初始化所有系统
*/
pub fn initialize(&mut self, context: &mut SystemContext) {
if !self.initialized {
for system in &mut self.systems {
system.initialize(context);
}
self.initialized = true;
}
}
/**
* 更新所有系统
*/
pub fn update(&mut self, context: &mut SystemContext) {
for system in &mut self.systems {
if system.enabled() {
system.update(context);
}
}
}
/**
* 后更新所有系统
*/
pub fn late_update(&mut self, context: &mut SystemContext) {
for system in &mut self.systems {
if system.enabled() {
system.late_update(context);
}
}
}
/**
* 清理所有系统
*/
pub fn cleanup(&mut self, context: &mut SystemContext) {
for system in &mut self.systems {
system.cleanup(context);
}
self.systems.clear();
self.initialized = false;
}
/**
* 获取系统数量
*/
pub fn system_count(&self) -> usize {
self.systems.len()
}
/**
* 获取启用的系统数量
*/
pub fn enabled_system_count(&self) -> usize {
self.systems.iter().filter(|s| s.enabled()).count()
}
/**
* 预留系统容量
*/
pub fn reserve_capacity(&mut self, capacity: usize) {
self.systems.reserve(capacity);
}
}
impl Default for SystemManager {
fn default() -> Self {
Self::new()
}
}

View File

@@ -0,0 +1,33 @@
// ECS Framework Rust Core - WASM Entry Point
// 只暴露用户需要操作的核心API内部实现保持私有
mod core;
mod storage;
mod utils;
mod wasm;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
macro_rules! console_log {
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
// 只导出WASM包装器隐藏内部实现
pub use wasm::{EntityWrapper, EntityManagerWrapper, QuerySystemWrapper, SceneWrapper, ComponentWrapper, ComponentRegistryWrapper};
// 导出核心类型供内部使用不暴露给JavaScript
pub use core::{Entity, Component, ComponentRegistry, BaseComponent, EntityManager, QuerySystem, QueryResult, Scene, System, EntitySystem, ProcessingSystem, IntervalSystem, SystemManager, ECSEventType, EventPriority, Event, EventListener, EventBus, EventBusStats, SimpleEventListener, ArchetypeSystem, Archetype, ArchetypeId, ArchetypeQueryResult, ArchetypeSystemStats, EntityBuilder, QueryBuilder, ECSFluentAPI, FluentAPIStats, PassiveSystem, PassiveSystemBuilder, ComponentBuilder, BaseComponentBuilder, ComponentBuilderFactory, ComponentBuilderStats, EntityBatchOperator, BatchOperatorStats, SceneBuilder, SceneTemplate, SceneBuilderStats, SceneBuilderFactory, SceneBuilderManager};
pub use storage::{ComponentStorage, ComponentStorageManager, SoAStorage, SoAFieldType, SoAFieldMetadata, SoAStorageStats, SoAFieldStats};
pub use utils::{SparseSet, Time, Matcher, QueryCondition, ComponentType, IdentifierPool, IdentifierPoolStats, ComponentPool, ComponentPoolManager, ComponentPoolStats, ComponentPoolManagerStats, PoolStatsSummary, DirtyTrackingSystem, DirtyFlag, DirtyData, DirtyTrackingStats, DirtyListener, DirtyListenerConfig, PerformanceMonitor, PerformanceData, PerformanceStats, PerformanceWarning, PerformanceWarningType, WarningSeverity, PerformanceThresholds, ThresholdPair, Timer, TimerManager, ITimer, TimerContext, TimerCallback, EmptyContext, Pool, PoolManager, Poolable, PoolStats, DebugManager, EntityDataCollector, SystemDataCollector, ComponentDataCollector, PerformanceDataCollector, DebugEntityData, DebugComponentInfo, DebugSystemInfo, DebugArchetypeInfo, DebugPerformanceInfo, DebugWarning, WarningLevel, DebugStats, DebugData, IUpdatable, IUpdatableComparer, SceneComponent, SceneComponentTrait, UpdatableManager, SceneComponentManager, is_updatable, NumberExtension, TypeUtils, StringExtension, CollectionExtension};
#[wasm_bindgen(start)]
pub fn main() {
utils::set_panic_hook();
console_log!("ECS Core Rust initialized - WASM API ready");
}

View File

@@ -0,0 +1,301 @@
use crate::core::component::{Component, ComponentRegistry};
use rustc_hash::FxHashMap;
use std::any::TypeId;
/**
* 高性能组件存储器
*/
pub struct ComponentStorage<T: Component + 'static> {
components: Vec<Option<T>>,
entity_to_index: FxHashMap<u32, usize>,
index_to_entity: Vec<u32>,
free_indices: Vec<usize>,
size: usize,
}
impl<T: Component + 'static> ComponentStorage<T> {
pub fn new() -> Self {
Self {
components: Vec::new(),
entity_to_index: FxHashMap::default(),
index_to_entity: Vec::new(),
free_indices: Vec::new(),
size: 0,
}
}
/**
* 添加组件
* @param entity_id 实体ID
* @param component 组件实例
*/
pub fn add_component(&mut self, entity_id: u32, component: T) -> Result<(), String> {
if self.entity_to_index.contains_key(&entity_id) {
return Err(format!("Entity {} already has this component", entity_id));
}
let index = if let Some(free_index) = self.free_indices.pop() {
self.components[free_index] = Some(component);
self.index_to_entity[free_index] = entity_id;
free_index
} else {
let index = self.components.len();
self.components.push(Some(component));
self.index_to_entity.push(entity_id);
index
};
self.entity_to_index.insert(entity_id, index);
self.size += 1;
Ok(())
}
/**
* 获取组件
* @param entity_id 实体ID
* @returns 组件引用或None
*/
pub fn get_component(&self, entity_id: u32) -> Option<&T> {
self.entity_to_index
.get(&entity_id)
.and_then(|&index| self.components.get(index))
.and_then(|component| component.as_ref())
}
/**
* 获取可变组件
* @param entity_id 实体ID
* @returns 可变组件引用或None
*/
pub fn get_component_mut(&mut self, entity_id: u32) -> Option<&mut T> {
self.entity_to_index
.get(&entity_id)
.and_then(|&index| self.components.get_mut(index))
.and_then(|component| component.as_mut())
}
/**
* 检查实体是否有此组件
* @param entity_id 实体ID
* @returns 是否有组件
*/
pub fn has_component(&self, entity_id: u32) -> bool {
self.entity_to_index.contains_key(&entity_id)
}
/**
* 移除组件
* @param entity_id 实体ID
* @returns 被移除的组件或None
*/
pub fn remove_component(&mut self, entity_id: u32) -> Option<T> {
let index = self.entity_to_index.remove(&entity_id)?;
let component = self.components[index].take()?;
self.free_indices.push(index);
self.size -= 1;
Some(component)
}
/**
* 高效遍历所有组件
* @param callback 回调函数
*/
pub fn for_each<F>(&self, mut callback: F)
where
F: FnMut(&T, u32, usize),
{
for (index, component) in self.components.iter().enumerate() {
if let Some(comp) = component {
let entity_id = self.index_to_entity[index];
callback(comp, entity_id, index);
}
}
}
/**
* 获取所有组件(密集数组)
*/
pub fn get_dense_array(&self) -> (Vec<&T>, Vec<u32>) {
let mut components = Vec::new();
let mut entity_ids = Vec::new();
for (index, component) in self.components.iter().enumerate() {
if let Some(comp) = component {
components.push(comp);
entity_ids.push(self.index_to_entity[index]);
}
}
(components, entity_ids)
}
/**
* 清空所有组件
*/
pub fn clear(&mut self) {
self.components.clear();
self.entity_to_index.clear();
self.index_to_entity.clear();
self.free_indices.clear();
self.size = 0;
}
/**
* 获取组件数量
*/
pub fn size(&self) -> usize {
self.size
}
/**
* 获取存储统计信息
*/
pub fn get_stats(&self) -> ComponentStorageStats {
let total_slots = self.components.len();
let used_slots = self.size;
let free_slots = self.free_indices.len();
let fragmentation = if total_slots > 0 {
free_slots as f32 / total_slots as f32
} else {
0.0
};
ComponentStorageStats {
total_slots,
used_slots,
free_slots,
fragmentation,
}
}
}
/**
* 组件存储统计信息
*/
pub struct ComponentStorageStats {
pub total_slots: usize,
pub used_slots: usize,
pub free_slots: usize,
pub fragmentation: f32,
}
/**
* 组件存储管理器
* 管理所有组件类型的存储器
*/
pub struct ComponentStorageManager {
storages: FxHashMap<TypeId, Box<dyn ComponentStorageInterface>>,
registry: ComponentRegistry,
}
impl ComponentStorageManager {
pub fn new() -> Self {
Self {
storages: FxHashMap::default(),
registry: ComponentRegistry::new(),
}
}
/**
* 获取组件注册表
*/
pub fn get_registry(&self) -> &ComponentRegistry {
&self.registry
}
/**
* 获取可变组件注册表
*/
pub fn get_registry_mut(&mut self) -> &mut ComponentRegistry {
&mut self.registry
}
/**
* 添加组件
* @param entity_id 实体ID
* @param component 组件实例
*/
pub fn add_component<T: Component + Clone + 'static>(&mut self, entity_id: u32, component: T) -> Result<(), String> {
let type_id = TypeId::of::<T>();
if !self.storages.contains_key(&type_id) {
let storage = Box::new(ComponentStorage::<T>::new());
self.storages.insert(type_id, storage);
}
if let Some(storage) = self.storages.get_mut(&type_id) {
storage.add_component_boxed(entity_id, Box::new(component))
} else {
Err("Failed to get storage".to_string())
}
}
/**
* 移除实体的所有组件
* @param entity_id 实体ID
*/
pub fn remove_all_components(&mut self, entity_id: u32) {
for storage in self.storages.values_mut() {
storage.remove_component_by_entity(entity_id);
}
}
/**
* 获取实体的组件位掩码
* @param entity_id 实体ID
* @returns 组件位掩码
*/
pub fn get_component_mask(&self, entity_id: u32) -> u64 {
let mut mask = 0u64;
for (&type_id, storage) in &self.storages {
if storage.has_component(entity_id) {
if let Some(bit_mask) = self.registry.get_bit_mask(&type_id) {
mask |= bit_mask;
}
}
}
mask
}
/**
* 清空所有存储器
*/
pub fn clear(&mut self) {
for storage in self.storages.values_mut() {
storage.clear();
}
self.storages.clear();
}
}
/**
* 组件存储接口
*/
trait ComponentStorageInterface: Send + Sync {
fn add_component_boxed(&mut self, entity_id: u32, component: Box<dyn Component>) -> Result<(), String>;
fn remove_component_by_entity(&mut self, entity_id: u32) -> bool;
fn has_component(&self, entity_id: u32) -> bool;
fn clear(&mut self);
}
impl<T: Component + Clone + 'static> ComponentStorageInterface for ComponentStorage<T> {
fn add_component_boxed(&mut self, entity_id: u32, component: Box<dyn Component>) -> Result<(), String> {
if let Some(downcasted) = component.as_any().downcast_ref::<T>() {
self.add_component(entity_id, downcasted.clone())
} else {
Err("Failed to downcast component".to_string())
}
}
fn remove_component_by_entity(&mut self, entity_id: u32) -> bool {
self.remove_component(entity_id).is_some()
}
fn has_component(&self, entity_id: u32) -> bool {
ComponentStorage::has_component(self, entity_id)
}
fn clear(&mut self) {
ComponentStorage::clear(self)
}
}

View File

@@ -0,0 +1,5 @@
pub mod component_storage;
pub mod soa_storage;
pub use component_storage::{ComponentStorage, ComponentStorageManager};
pub use soa_storage::{SoAStorage, SoAFieldType, SoAFieldMetadata, SoAStorageStats, SoAFieldStats};

View File

@@ -0,0 +1,999 @@
use crate::core::Component;
use crate::utils::ComponentType;
use rustc_hash::FxHashMap;
use std::any::Any;
use std::marker::PhantomData;
/**
* SoA字段类型枚举
* 定义TypedArray字段的存储类型
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SoAFieldType {
Float32,
Float64,
Int32,
Boolean,
String,
Serialized,
Complex,
}
/**
* SoA字段元数据
* 记录字段的配置信息
*/
#[derive(Debug, Clone)]
pub struct SoAFieldMetadata {
pub field_type: SoAFieldType,
pub high_precision: bool,
pub serialize_map: bool,
pub serialize_set: bool,
pub serialize_array: bool,
pub deep_copy: bool,
}
impl Default for SoAFieldMetadata {
fn default() -> Self {
Self {
field_type: SoAFieldType::Float32,
high_precision: false,
serialize_map: false,
serialize_set: false,
serialize_array: false,
deep_copy: false,
}
}
}
/**
* SoA存储统计信息
*/
#[derive(Debug, Clone)]
pub struct SoAStorageStats {
pub size: usize,
pub capacity: usize,
pub used_slots: usize,
pub fragmentation: f64,
pub memory_usage: usize,
pub field_stats: FxHashMap<String, SoAFieldStats>,
}
/**
* SoA字段统计信息
*/
#[derive(Debug, Clone)]
pub struct SoAFieldStats {
pub size: usize,
pub capacity: usize,
pub field_type: String,
pub memory: usize,
}
/**
* SoA存储器
* 使用Structure of Arrays存储模式在大规模批量操作时提供优异性能
*/
pub struct SoAStorage<T: Component> {
/// Float32数值字段
float32_fields: FxHashMap<String, Vec<f32>>,
/// Float64数值字段
float64_fields: FxHashMap<String, Vec<f64>>,
/// Int32数值字段
int32_fields: FxHashMap<String, Vec<i32>>,
/// 字符串字段
string_fields: FxHashMap<String, Vec<Option<String>>>,
/// 序列化字段(用于复杂对象)
serialized_fields: FxHashMap<String, Vec<Option<String>>>,
/// 复杂对象字段(高精度或非序列化对象)
complex_fields: FxHashMap<u32, FxHashMap<String, Box<dyn Any + Send>>>,
/// 实体ID到索引的映射
entity_to_index: FxHashMap<u32, usize>,
/// 索引到实体ID的映射
index_to_entity: Vec<Option<u32>>,
/// 空闲索引列表
free_indices: Vec<usize>,
/// 当前大小
size: usize,
/// 当前容量
capacity: usize,
/// 组件类型
component_type: ComponentType,
/// 字段元数据
field_metadata: FxHashMap<String, SoAFieldMetadata>,
/// 类型标记
_phantom: PhantomData<T>,
}
impl<T: Component> SoAStorage<T> {
/**
* 创建新的SoA存储器
*/
pub fn new() -> Self {
let initial_capacity = 1000;
Self {
float32_fields: FxHashMap::default(),
float64_fields: FxHashMap::default(),
int32_fields: FxHashMap::default(),
string_fields: FxHashMap::default(),
serialized_fields: FxHashMap::default(),
complex_fields: FxHashMap::default(),
entity_to_index: FxHashMap::default(),
index_to_entity: vec![None; initial_capacity],
free_indices: Vec::new(),
size: 0,
capacity: initial_capacity,
component_type: std::any::TypeId::of::<T>(),
field_metadata: FxHashMap::default(),
_phantom: PhantomData,
}
}
/**
* 使用指定容量创建SoA存储器
*/
pub fn with_capacity(capacity: usize) -> Self {
Self {
float32_fields: FxHashMap::default(),
float64_fields: FxHashMap::default(),
int32_fields: FxHashMap::default(),
string_fields: FxHashMap::default(),
serialized_fields: FxHashMap::default(),
complex_fields: FxHashMap::default(),
entity_to_index: FxHashMap::default(),
index_to_entity: vec![None; capacity],
free_indices: Vec::new(),
size: 0,
capacity,
component_type: std::any::TypeId::of::<T>(),
field_metadata: FxHashMap::default(),
_phantom: PhantomData,
}
}
/**
* 初始化字段结构
* 根据组件类型的特征来设置字段存储类型
*/
pub fn initialize_fields(&mut self) {
// 在Rust中我们需要手动注册字段类型
// 这里提供一个基础的初始化具体的字段配置需要通过register_field方法添加
}
/**
* 注册字段
*/
pub fn register_field(&mut self, field_name: &str, metadata: SoAFieldMetadata) {
self.field_metadata.insert(field_name.to_string(), metadata.clone());
match metadata.field_type {
SoAFieldType::Float32 => {
self.float32_fields.insert(field_name.to_string(), vec![0.0; self.capacity]);
},
SoAFieldType::Float64 => {
self.float64_fields.insert(field_name.to_string(), vec![0.0; self.capacity]);
},
SoAFieldType::Int32 => {
self.int32_fields.insert(field_name.to_string(), vec![0; self.capacity]);
},
SoAFieldType::Boolean => {
// 布尔值使用Float32存储为0/1
self.float32_fields.insert(field_name.to_string(), vec![0.0; self.capacity]);
},
SoAFieldType::String => {
self.string_fields.insert(field_name.to_string(), vec![None; self.capacity]);
},
SoAFieldType::Serialized => {
self.serialized_fields.insert(field_name.to_string(), vec![None; self.capacity]);
},
SoAFieldType::Complex => {
// 复杂字段在运行时按需添加到complex_fields中
},
}
}
/**
* 添加组件
*/
pub fn add_component(&mut self, entity_id: u32, component: T) {
if let Some(index) = self.entity_to_index.get(&entity_id) {
// 更新现有组件
self.update_component_at_index(*index, entity_id, component);
return;
}
// 获取可用索引
let index = if let Some(free_index) = self.free_indices.pop() {
free_index
} else {
if self.size >= self.capacity {
self.resize(self.capacity * 2);
}
self.size
};
// 设置映射关系
self.entity_to_index.insert(entity_id, index);
self.index_to_entity[index] = Some(entity_id);
// 更新组件数据
self.update_component_at_index(index, entity_id, component);
if index == self.size {
self.size += 1;
}
}
/**
* 在指定索引处更新组件数据
*/
fn update_component_at_index(&mut self, index: usize, entity_id: u32, component: T) {
// 在Rust中我们无法像TypeScript那样动态遍历对象属性
// 需要使用trait或者其他方式来序列化组件数据
// 这里提供一个基础实现,具体的字段设置需要在具体使用时实现
// 将组件转换为Any trait对象存储在complex_fields中
let mut entity_complex_fields = FxHashMap::default();
entity_complex_fields.insert("component".to_string(), Box::new(component) as Box<dyn Any + Send>);
self.complex_fields.insert(entity_id, entity_complex_fields);
}
/**
* 获取组件
*/
pub fn get_component(&self, entity_id: u32) -> Option<&T> {
if let Some(index) = self.entity_to_index.get(&entity_id) {
if let Some(complex_fields) = self.complex_fields.get(&entity_id) {
if let Some(component_any) = complex_fields.get("component") {
if let Some(component) = component_any.downcast_ref::<T>() {
return Some(component);
}
}
}
}
None
}
/**
* 获取可变组件引用
*/
pub fn get_component_mut(&mut self, entity_id: u32) -> Option<&mut T> {
if let Some(_index) = self.entity_to_index.get(&entity_id) {
if let Some(complex_fields) = self.complex_fields.get_mut(&entity_id) {
if let Some(component_any) = complex_fields.get_mut("component") {
if let Some(component) = component_any.downcast_mut::<T>() {
return Some(component);
}
}
}
}
None
}
/**
* 检查是否包含指定实体的组件
*/
pub fn has_component(&self, entity_id: u32) -> bool {
self.entity_to_index.contains_key(&entity_id)
}
/**
* 移除组件
*/
pub fn remove_component(&mut self, entity_id: u32) -> bool {
if let Some(index) = self.entity_to_index.remove(&entity_id) {
// 清理复杂字段
self.complex_fields.remove(&entity_id);
// 清理索引映射
self.index_to_entity[index] = None;
self.free_indices.push(index);
// 清理各类型字段的数据(设为默认值)
for array in self.float32_fields.values_mut() {
if index < array.len() {
array[index] = 0.0;
}
}
for array in self.float64_fields.values_mut() {
if index < array.len() {
array[index] = 0.0;
}
}
for array in self.int32_fields.values_mut() {
if index < array.len() {
array[index] = 0;
}
}
for array in self.string_fields.values_mut() {
if index < array.len() {
array[index] = None;
}
}
for array in self.serialized_fields.values_mut() {
if index < array.len() {
array[index] = None;
}
}
true
} else {
false
}
}
/**
* 调整存储容量
*/
fn resize(&mut self, new_capacity: usize) {
// 调整数值字段
for array in self.float32_fields.values_mut() {
array.resize(new_capacity, 0.0);
}
for array in self.float64_fields.values_mut() {
array.resize(new_capacity, 0.0);
}
for array in self.int32_fields.values_mut() {
array.resize(new_capacity, 0);
}
for array in self.string_fields.values_mut() {
array.resize(new_capacity, None);
}
for array in self.serialized_fields.values_mut() {
array.resize(new_capacity, None);
}
// 调整索引映射
self.index_to_entity.resize(new_capacity, None);
self.capacity = new_capacity;
}
/**
* 获取活跃索引列表
*/
pub fn get_active_indices(&self) -> Vec<usize> {
self.entity_to_index.values().cloned().collect()
}
/**
* 获取Float32字段数组
*/
pub fn get_float32_field(&self, field_name: &str) -> Option<&[f32]> {
self.float32_fields.get(field_name).map(|v| v.as_slice())
}
/**
* 获取可变Float32字段数组
*/
pub fn get_float32_field_mut(&mut self, field_name: &str) -> Option<&mut [f32]> {
self.float32_fields.get_mut(field_name).map(|v| v.as_mut_slice())
}
/**
* 获取Float64字段数组
*/
pub fn get_float64_field(&self, field_name: &str) -> Option<&[f64]> {
self.float64_fields.get(field_name).map(|v| v.as_slice())
}
/**
* 获取可变Float64字段数组
*/
pub fn get_float64_field_mut(&mut self, field_name: &str) -> Option<&mut [f64]> {
self.float64_fields.get_mut(field_name).map(|v| v.as_mut_slice())
}
/**
* 获取Int32字段数组
*/
pub fn get_int32_field(&self, field_name: &str) -> Option<&[i32]> {
self.int32_fields.get(field_name).map(|v| v.as_slice())
}
/**
* 获取可变Int32字段数组
*/
pub fn get_int32_field_mut(&mut self, field_name: &str) -> Option<&mut [i32]> {
self.int32_fields.get_mut(field_name).map(|v| v.as_mut_slice())
}
/**
* 获取实体索引
*/
pub fn get_entity_index(&self, entity_id: u32) -> Option<usize> {
self.entity_to_index.get(&entity_id).copied()
}
/**
* 根据索引获取实体ID
*/
pub fn get_entity_id_by_index(&self, index: usize) -> Option<u32> {
if index < self.index_to_entity.len() {
self.index_to_entity[index]
} else {
None
}
}
/**
* 获取当前大小
*/
pub fn size(&self) -> usize {
self.size - self.free_indices.len()
}
/**
* 获取容量
*/
pub fn capacity(&self) -> usize {
self.capacity
}
/**
* 清空所有数据
*/
pub fn clear(&mut self) {
self.entity_to_index.clear();
self.complex_fields.clear();
self.free_indices.clear();
self.size = 0;
// 重置所有字段数组
for array in self.float32_fields.values_mut() {
array.fill(0.0);
}
for array in self.float64_fields.values_mut() {
array.fill(0.0);
}
for array in self.int32_fields.values_mut() {
array.fill(0);
}
for array in self.string_fields.values_mut() {
array.fill(None);
}
for array in self.serialized_fields.values_mut() {
array.fill(None);
}
for i in 0..self.index_to_entity.len() {
self.index_to_entity[i] = None;
}
}
/**
* 压缩存储(移除空洞)
*/
pub fn compact(&mut self) {
if self.free_indices.is_empty() {
return;
}
// 收集所有活跃的实体并按索引排序
let mut active_entries: Vec<(u32, usize)> = self.entity_to_index.iter()
.map(|(&entity_id, &index)| (entity_id, index))
.collect();
active_entries.sort_by_key(|(_, index)| *index);
// 重新映射索引
let mut new_entity_to_index = FxHashMap::default();
let mut new_index_to_entity = vec![None; self.capacity];
for (new_index, (entity_id, old_index)) in active_entries.iter().enumerate() {
new_entity_to_index.insert(*entity_id, new_index);
new_index_to_entity[new_index] = Some(*entity_id);
if new_index != *old_index {
// 移动数据
self.move_data_between_indices(*old_index, new_index);
}
}
self.entity_to_index = new_entity_to_index;
self.index_to_entity = new_index_to_entity;
self.free_indices.clear();
self.size = active_entries.len();
}
/**
* 在索引间移动数据
*/
fn move_data_between_indices(&mut self, from: usize, to: usize) {
// 移动Float32字段
for array in self.float32_fields.values_mut() {
if from < array.len() && to < array.len() {
array[to] = array[from];
}
}
// 移动Float64字段
for array in self.float64_fields.values_mut() {
if from < array.len() && to < array.len() {
array[to] = array[from];
}
}
// 移动Int32字段
for array in self.int32_fields.values_mut() {
if from < array.len() && to < array.len() {
array[to] = array[from];
}
}
// 移动String字段
for array in self.string_fields.values_mut() {
if from < array.len() && to < array.len() {
array[to] = array[from].take();
}
}
// 移动序列化字段
for array in self.serialized_fields.values_mut() {
if from < array.len() && to < array.len() {
array[to] = array[from].take();
}
}
}
/**
* 获取存储统计信息
*/
pub fn get_stats(&self) -> SoAStorageStats {
let mut total_memory = 0usize;
let mut field_stats = FxHashMap::default();
// 计算Float32字段统计
for (field_name, array) in &self.float32_fields {
let memory = array.len() * std::mem::size_of::<f32>();
total_memory += memory;
field_stats.insert(field_name.clone(), SoAFieldStats {
size: self.size(),
capacity: array.len(),
field_type: "float32".to_string(),
memory,
});
}
// 计算Float64字段统计
for (field_name, array) in &self.float64_fields {
let memory = array.len() * std::mem::size_of::<f64>();
total_memory += memory;
field_stats.insert(field_name.clone(), SoAFieldStats {
size: self.size(),
capacity: array.len(),
field_type: "float64".to_string(),
memory,
});
}
// 计算Int32字段统计
for (field_name, array) in &self.int32_fields {
let memory = array.len() * std::mem::size_of::<i32>();
total_memory += memory;
field_stats.insert(field_name.clone(), SoAFieldStats {
size: self.size(),
capacity: array.len(),
field_type: "int32".to_string(),
memory,
});
}
// 估算字符串和序列化字段内存(简单估算)
for (field_name, array) in &self.string_fields {
let estimated_memory = array.len() * 64; // 假设平均64字节每个字符串
total_memory += estimated_memory;
field_stats.insert(field_name.clone(), SoAFieldStats {
size: self.size(),
capacity: array.len(),
field_type: "string".to_string(),
memory: estimated_memory,
});
}
SoAStorageStats {
size: self.size(),
capacity: self.capacity,
used_slots: self.size(),
fragmentation: self.free_indices.len() as f64 / self.capacity as f64,
memory_usage: total_memory,
field_stats,
}
}
/**
* 执行向量化批量操作
*/
pub fn perform_vectorized_operation<F>(&mut self, operation: F)
where
F: FnOnce(&mut SoAStorage<T>),
{
operation(self);
}
}
impl<T: Component> Default for SoAStorage<T> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::Any;
// 测试组件
#[derive(Debug, Clone)]
struct TestComponent {
pub x: f32,
pub y: f32,
pub name: String,
pub active: bool,
pub id: u32,
pub enabled: bool,
pub update_order: i32,
}
impl TestComponent {
fn new() -> Self {
Self {
x: 0.0,
y: 0.0,
name: String::new(),
active: false,
id: 0,
enabled: true,
update_order: 0,
}
}
}
impl Component for TestComponent {
fn id(&self) -> u32 {
self.id
}
fn enabled(&self) -> bool {
self.enabled
}
fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
fn update_order(&self) -> i32 {
self.update_order
}
fn set_update_order(&mut self, order: i32) {
self.update_order = order;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn clone_box(&self) -> Box<dyn Component> {
Box::new(self.clone())
}
}
#[test]
fn test_soa_storage_creation() {
let storage: SoAStorage<TestComponent> = SoAStorage::new();
assert_eq!(storage.size(), 0);
assert_eq!(storage.capacity(), 1000);
}
#[test]
fn test_soa_storage_with_capacity() {
let storage: SoAStorage<TestComponent> = SoAStorage::with_capacity(500);
assert_eq!(storage.size(), 0);
assert_eq!(storage.capacity(), 500);
}
#[test]
fn test_field_registration() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
storage.register_field("x", SoAFieldMetadata {
field_type: SoAFieldType::Float32,
..Default::default()
});
storage.register_field("name", SoAFieldMetadata {
field_type: SoAFieldType::String,
..Default::default()
});
assert!(storage.get_float32_field("x").is_some());
assert_eq!(storage.get_float32_field("x").unwrap().len(), 1000);
}
#[test]
fn test_component_add_remove() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
let component = TestComponent {
x: 1.0,
y: 2.0,
name: "test".to_string(),
active: true,
id: 1,
enabled: true,
update_order: 0,
};
let entity_id = 1;
// 添加组件
storage.add_component(entity_id, component.clone());
assert_eq!(storage.size(), 1);
assert!(storage.has_component(entity_id));
// 获取组件
let retrieved = storage.get_component(entity_id);
assert!(retrieved.is_some());
// 移除组件
assert!(storage.remove_component(entity_id));
assert_eq!(storage.size(), 0);
assert!(!storage.has_component(entity_id));
}
#[test]
fn test_multiple_components() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
for i in 1..=10 {
let component = TestComponent {
x: i as f32,
y: i as f32 * 2.0,
name: format!("test{}", i),
active: i % 2 == 0,
id: i,
enabled: true,
update_order: 0,
};
storage.add_component(i, component);
}
assert_eq!(storage.size(), 10);
// 验证所有组件都存在
for i in 1..=10 {
assert!(storage.has_component(i));
}
// 移除一半组件
for i in (1..=10).step_by(2) {
storage.remove_component(i);
}
assert_eq!(storage.size(), 5);
}
#[test]
fn test_storage_resize() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::with_capacity(5);
// 添加超过初始容量的组件
for i in 1..=10 {
let component = TestComponent {
x: i as f32,
y: i as f32,
name: format!("test{}", i),
active: true,
id: i,
enabled: true,
update_order: 0,
};
storage.add_component(i, component);
}
assert_eq!(storage.size(), 10);
assert!(storage.capacity() >= 10); // 应该已经扩容
}
#[test]
fn test_storage_clear() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
// 添加一些组件
for i in 1..=5 {
let component = TestComponent {
x: i as f32,
y: i as f32,
name: format!("test{}", i),
active: true,
id: i,
enabled: true,
update_order: 0,
};
storage.add_component(i, component);
}
assert_eq!(storage.size(), 5);
storage.clear();
assert_eq!(storage.size(), 0);
for i in 1..=5 {
assert!(!storage.has_component(i));
}
}
#[test]
fn test_storage_compact() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
// 添加组件
for i in 1..=10 {
let component = TestComponent {
x: i as f32,
y: i as f32,
name: format!("test{}", i),
active: true,
id: i,
enabled: true,
update_order: 0,
};
storage.add_component(i, component);
}
// 移除一些组件制造空洞
storage.remove_component(2);
storage.remove_component(4);
storage.remove_component(6);
assert_eq!(storage.size(), 7);
assert_eq!(storage.free_indices.len(), 3);
storage.compact();
assert_eq!(storage.size(), 7);
assert!(storage.free_indices.is_empty());
}
#[test]
fn test_storage_stats() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
storage.register_field("x", SoAFieldMetadata {
field_type: SoAFieldType::Float32,
..Default::default()
});
storage.register_field("y", SoAFieldMetadata {
field_type: SoAFieldType::Float64,
..Default::default()
});
let component = TestComponent {
x: 1.0,
y: 2.0,
name: "test".to_string(),
active: true,
id: 1,
enabled: true,
update_order: 0,
};
storage.add_component(1, component);
let stats = storage.get_stats();
assert_eq!(stats.size, 1);
assert_eq!(stats.capacity, 1000);
assert!(stats.memory_usage > 0);
assert!(!stats.field_stats.is_empty());
}
#[test]
fn test_vectorized_operation() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
storage.register_field("x", SoAFieldMetadata {
field_type: SoAFieldType::Float32,
..Default::default()
});
// 设置初始数据到Float32字段中
if let Some(x_field) = storage.get_float32_field_mut("x") {
for i in 0..5 {
x_field[i] = (i + 1) as f32;
}
}
// 执行向量化操作
storage.perform_vectorized_operation(|storage| {
if let Some(x_field) = storage.get_float32_field_mut("x") {
// 将所有x值乘以2
for i in 0..5 {
x_field[i] *= 2.0;
}
}
});
// 验证操作结果
if let Some(x_field) = storage.get_float32_field("x") {
assert_eq!(x_field[0], 2.0); // 第一个元素应该是2
}
}
#[test]
fn test_entity_index_mapping() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
let component = TestComponent {
x: 1.0,
y: 2.0,
name: "test".to_string(),
active: true,
id: 1,
enabled: true,
update_order: 0,
};
storage.add_component(100, component);
let index = storage.get_entity_index(100);
assert!(index.is_some());
let entity_id = storage.get_entity_id_by_index(index.unwrap());
assert_eq!(entity_id, Some(100));
}
#[test]
fn test_active_indices() {
let mut storage: SoAStorage<TestComponent> = SoAStorage::new();
let component1 = TestComponent {
x: 1.0,
y: 1.0,
name: "test1".to_string(),
active: true,
id: 1,
enabled: true,
update_order: 0,
};
let component2 = TestComponent {
x: 2.0,
y: 2.0,
name: "test2".to_string(),
active: true,
id: 2,
enabled: true,
update_order: 0,
};
storage.add_component(1, component1);
storage.add_component(2, component2);
let active_indices = storage.get_active_indices();
assert_eq!(active_indices.len(), 2);
storage.remove_component(1);
let active_indices = storage.get_active_indices();
assert_eq!(active_indices.len(), 1);
}
}

View File

@@ -0,0 +1,766 @@
use crate::core::Component;
use crate::utils::ComponentType;
use rustc_hash::FxHashMap;
use std::any::Any;
/**
* 组件对象池,用于复用组件实例以减少内存分配
*/
pub struct ComponentPool<T>
where
T: Component + Clone + Default,
{
/// 池中存储的组件实例
pool: Vec<T>,
/// 创建新组件实例的函数
create_fn: Box<dyn Fn() -> T + Send + Sync>,
/// 重置组件状态的函数(可选)
reset_fn: Option<Box<dyn Fn(&mut T) + Send + Sync>>,
/// 池的最大容量
max_size: usize,
/// 统计信息
stats: ComponentPoolStats,
}
/**
* 组件池统计信息
*/
#[derive(Debug, Clone)]
pub struct ComponentPoolStats {
/// 总共创建的组件数量
pub total_created: u32,
/// 总共获取的次数
pub total_acquires: u32,
/// 总共释放的次数
pub total_releases: u32,
/// 池命中次数(从池中获取而不是创建新的)
pub pool_hits: u32,
/// 池未命中次数(需要创建新实例)
pub pool_misses: u32,
}
impl Default for ComponentPoolStats {
fn default() -> Self {
Self {
total_created: 0,
total_acquires: 0,
total_releases: 0,
pool_hits: 0,
pool_misses: 0,
}
}
}
impl<T> ComponentPool<T>
where
T: Component + Clone + Default,
{
/**
* 创建新的组件池
*/
pub fn new<F, R>(create_fn: F, reset_fn: Option<R>, max_size: usize) -> Self
where
F: Fn() -> T + Send + Sync + 'static,
R: Fn(&mut T) + Send + Sync + 'static,
{
Self {
pool: Vec::with_capacity(max_size.min(100)), // 预分配一些空间
create_fn: Box::new(create_fn),
reset_fn: reset_fn.map(|f| Box::new(f) as Box<dyn Fn(&mut T) + Send + Sync>),
max_size,
stats: ComponentPoolStats::default(),
}
}
/**
* 创建默认的组件池使用Default trait
*/
pub fn with_default(max_size: usize) -> Self {
Self::new(T::default, None::<fn(&mut T)>, max_size)
}
/**
* 创建带重置函数的默认组件池
*/
pub fn with_default_and_reset<R>(reset_fn: R, max_size: usize) -> Self
where
R: Fn(&mut T) + Send + Sync + 'static,
{
Self::new(T::default, Some(reset_fn), max_size)
}
/**
* 获取一个组件实例
*/
pub fn acquire(&mut self) -> T {
self.stats.total_acquires += 1;
if let Some(component) = self.pool.pop() {
self.stats.pool_hits += 1;
component
} else {
self.stats.pool_misses += 1;
self.stats.total_created += 1;
(self.create_fn)()
}
}
/**
* 释放一个组件实例回池中
*/
pub fn release(&mut self, mut component: T) {
self.stats.total_releases += 1;
if self.pool.len() < self.max_size {
// 调用重置函数(如果有)
if let Some(ref reset_fn) = self.reset_fn {
reset_fn(&mut component);
}
self.pool.push(component);
}
// 如果池已满组件会被丢弃由Rust自动清理
}
/**
* 预填充对象池
*/
pub fn prewarm(&mut self, count: usize) {
let needed = (self.max_size - self.pool.len()).min(count);
for _ in 0..needed {
let component = (self.create_fn)();
self.pool.push(component);
self.stats.total_created += 1;
}
}
/**
* 清空对象池
*/
pub fn clear(&mut self) {
self.pool.clear();
}
/**
* 获取池中可用对象数量
*/
pub fn available_count(&self) -> usize {
self.pool.len()
}
/**
* 获取池的最大容量
*/
pub fn max_size(&self) -> usize {
self.max_size
}
/**
* 获取使用中的对象数量估算
*/
pub fn used_count(&self) -> u32 {
// 基于统计信息估算(总创建 - 池中可用)
if self.stats.total_created as usize >= self.pool.len() {
self.stats.total_created - self.pool.len() as u32
} else {
0
}
}
/**
* 获取池利用率(百分比)
*/
pub fn utilization_rate(&self) -> f32 {
if self.max_size == 0 {
return 0.0;
}
let used = self.used_count() as f32;
let total = self.max_size as f32;
(used / total) * 100.0
}
/**
* 获取池命中率(百分比)
*/
pub fn hit_rate(&self) -> f32 {
if self.stats.total_acquires == 0 {
return 0.0;
}
(self.stats.pool_hits as f32 / self.stats.total_acquires as f32) * 100.0
}
/**
* 获取统计信息
*/
pub fn get_stats(&self) -> ComponentPoolStats {
self.stats.clone()
}
/**
* 重置统计信息
*/
pub fn reset_stats(&mut self) {
self.stats = ComponentPoolStats::default();
}
/**
* 获取内存使用估算(字节)
*/
pub fn estimated_memory_usage(&self) -> usize {
let component_size = std::mem::size_of::<T>();
let pool_size = self.pool.len() * component_size;
let vec_overhead = self.pool.capacity() * std::mem::size_of::<T>();
pool_size + vec_overhead
}
}
/**
* 类型擦除的组件池特征
* 用于在ComponentPoolManager中统一管理不同类型的池
*/
trait AnyComponentPool {
fn clear(&mut self);
fn available_count(&self) -> usize;
fn max_size(&self) -> usize;
fn used_count(&self) -> u32;
fn utilization_rate(&self) -> f32;
fn hit_rate(&self) -> f32;
fn estimated_memory_usage(&self) -> usize;
fn prewarm(&mut self, count: usize);
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T> AnyComponentPool for ComponentPool<T>
where
T: Component + Clone + Default,
{
fn clear(&mut self) {
self.clear();
}
fn available_count(&self) -> usize {
self.available_count()
}
fn max_size(&self) -> usize {
self.max_size()
}
fn used_count(&self) -> u32 {
self.used_count()
}
fn utilization_rate(&self) -> f32 {
self.utilization_rate()
}
fn hit_rate(&self) -> f32 {
self.hit_rate()
}
fn estimated_memory_usage(&self) -> usize {
self.estimated_memory_usage()
}
fn prewarm(&mut self, count: usize) {
self.prewarm(count);
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 池统计信息摘要
*/
#[derive(Debug, Clone)]
pub struct PoolStatsSummary {
pub available: usize,
pub max_size: usize,
pub used: u32,
pub utilization_rate: f32,
pub hit_rate: f32,
pub memory_usage: usize,
}
/**
* 全局组件池管理器
* 使用单例模式管理所有组件类型的对象池
*/
pub struct ComponentPoolManager {
/// 存储各种组件类型的池
pools: FxHashMap<ComponentType, Box<dyn AnyComponentPool>>,
/// 管理器统计信息
stats: ComponentPoolManagerStats,
}
/**
* 组件池管理器统计信息
*/
#[derive(Debug, Clone)]
pub struct ComponentPoolManagerStats {
pub registered_pools: u32,
pub total_memory_usage: usize,
pub total_components_managed: u32,
}
impl Default for ComponentPoolManagerStats {
fn default() -> Self {
Self {
registered_pools: 0,
total_memory_usage: 0,
total_components_managed: 0,
}
}
}
impl ComponentPoolManager {
/**
* 创建新的组件池管理器
*/
pub fn new() -> Self {
Self {
pools: FxHashMap::default(),
stats: ComponentPoolManagerStats::default(),
}
}
/**
* 注册组件池
*/
pub fn register_pool<T, F, R>(
&mut self,
component_type: ComponentType,
create_fn: F,
reset_fn: Option<R>,
max_size: Option<usize>,
) where
T: Component + Clone + Default + 'static,
F: Fn() -> T + Send + Sync + 'static,
R: Fn(&mut T) + Send + Sync + 'static,
{
let max_size = max_size.unwrap_or(1000);
let pool = ComponentPool::new(create_fn, reset_fn, max_size);
self.pools.insert(component_type, Box::new(pool));
self.update_stats();
}
/**
* 注册使用Default的组件池
*/
pub fn register_pool_default<T>(&mut self, component_type: ComponentType, max_size: Option<usize>)
where
T: Component + Clone + Default + 'static,
{
let max_size = max_size.unwrap_or(1000);
let pool = ComponentPool::<T>::with_default(max_size);
self.pools.insert(component_type, Box::new(pool));
self.update_stats();
}
/**
* 获取组件实例
*/
pub fn acquire_component<T>(&mut self, component_type: ComponentType) -> Option<T>
where
T: Component + Clone + Default + 'static,
{
if let Some(pool) = self.pools.get_mut(&component_type) {
if let Some(typed_pool) = pool.as_any_mut().downcast_mut::<ComponentPool<T>>() {
return Some(typed_pool.acquire());
}
}
None
}
/**
* 释放组件实例
*/
pub fn release_component<T>(&mut self, component_type: ComponentType, component: T)
where
T: Component + Clone + Default + 'static,
{
if let Some(pool) = self.pools.get_mut(&component_type) {
if let Some(typed_pool) = pool.as_any_mut().downcast_mut::<ComponentPool<T>>() {
typed_pool.release(component);
}
}
}
/**
* 预热所有池
*/
pub fn prewarm_all(&mut self, count: usize) {
for pool in self.pools.values_mut() {
pool.prewarm(count);
}
self.update_stats();
}
/**
* 预热指定池
*/
pub fn prewarm_pool(&mut self, component_type: ComponentType, count: usize) {
if let Some(pool) = self.pools.get_mut(&component_type) {
pool.prewarm(count);
self.update_stats();
}
}
/**
* 清空所有池
*/
pub fn clear_all(&mut self) {
for pool in self.pools.values_mut() {
pool.clear();
}
self.update_stats();
}
/**
* 清空指定池
*/
pub fn clear_pool(&mut self, component_type: ComponentType) {
if let Some(pool) = self.pools.get_mut(&component_type) {
pool.clear();
self.update_stats();
}
}
/**
* 移除所有注册的池
*/
pub fn reset(&mut self) {
self.pools.clear();
self.stats = ComponentPoolManagerStats::default();
}
/**
* 获取池统计信息
*/
pub fn get_pool_stats(&self) -> FxHashMap<ComponentType, PoolStatsSummary> {
let mut stats = FxHashMap::default();
for (&component_type, pool) in &self.pools {
let summary = PoolStatsSummary {
available: pool.available_count(),
max_size: pool.max_size(),
used: pool.used_count(),
utilization_rate: pool.utilization_rate(),
hit_rate: pool.hit_rate(),
memory_usage: pool.estimated_memory_usage(),
};
stats.insert(component_type, summary);
}
stats
}
/**
* 获取指定组件的池利用率
*/
pub fn get_component_utilization(&self, component_type: ComponentType) -> f32 {
self.pools.get(&component_type)
.map(|pool| pool.utilization_rate())
.unwrap_or(0.0)
}
/**
* 获取指定组件的池命中率
*/
pub fn get_component_hit_rate(&self, component_type: ComponentType) -> f32 {
self.pools.get(&component_type)
.map(|pool| pool.hit_rate())
.unwrap_or(0.0)
}
/**
* 获取管理器统计信息
*/
pub fn get_manager_stats(&self) -> ComponentPoolManagerStats {
self.stats.clone()
}
/**
* 获取所有池的总内存使用量
*/
pub fn get_total_memory_usage(&self) -> usize {
self.pools.values()
.map(|pool| pool.estimated_memory_usage())
.sum()
}
/**
* 检查是否注册了指定组件类型的池
*/
pub fn has_pool(&self, component_type: ComponentType) -> bool {
self.pools.contains_key(&component_type)
}
/**
* 获取注册的池数量
*/
pub fn pool_count(&self) -> usize {
self.pools.len()
}
// 私有方法
/**
* 更新管理器统计信息
*/
fn update_stats(&mut self) {
self.stats.registered_pools = self.pools.len() as u32;
self.stats.total_memory_usage = self.get_total_memory_usage();
self.stats.total_components_managed = self.pools.values()
.map(|pool| pool.used_count() + pool.available_count() as u32)
.sum();
}
}
impl Default for ComponentPoolManager {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::TypeId;
// 测试用的示例组件
#[derive(Clone, Default, Debug, PartialEq)]
struct TestComponent {
pub value: i32,
pub name: String,
}
impl Component for TestComponent {
fn id(&self) -> u32 { 0 }
fn set_enabled(&mut self, _enabled: bool) {}
fn set_update_order(&mut self, _order: i32) {}
fn as_any(&self) -> &dyn std::any::Any { self }
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
fn clone_box(&self) -> Box<dyn Component> { Box::new(self.clone()) }
}
#[derive(Clone, Default, Debug)]
struct AnotherTestComponent {
pub data: String,
}
impl Component for AnotherTestComponent {
fn id(&self) -> u32 { 0 }
fn set_enabled(&mut self, _enabled: bool) {}
fn set_update_order(&mut self, _order: i32) {}
fn as_any(&self) -> &dyn std::any::Any { self }
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
fn clone_box(&self) -> Box<dyn Component> { Box::new(self.clone()) }
}
#[test]
fn test_component_pool_basic() {
let pool = ComponentPool::<TestComponent>::with_default(10);
// 测试基本属性
assert_eq!(pool.available_count(), 0);
assert_eq!(pool.max_size(), 10);
assert_eq!(pool.utilization_rate(), 0.0);
}
#[test]
fn test_component_pool_acquire_release() {
let mut pool = ComponentPool::<TestComponent>::with_default(5);
// 第一次获取应该创建新实例
let mut component1 = pool.acquire();
component1.value = 42;
component1.name = "test".to_string();
assert_eq!(pool.available_count(), 0);
assert_eq!(pool.get_stats().pool_misses, 1);
// 释放组件
pool.release(component1);
assert_eq!(pool.available_count(), 1);
// 再次获取应该从池中获取
let component2 = pool.acquire();
assert_eq!(pool.available_count(), 0);
assert_eq!(pool.get_stats().pool_hits, 1);
// 验证是同一个实例(虽然值可能不同)
assert_eq!(component2.value, 42); // 没有重置函数,值保持不变
}
#[test]
fn test_component_pool_with_reset() {
let reset_fn = |comp: &mut TestComponent| {
comp.value = 0;
comp.name.clear();
};
let mut pool = ComponentPool::with_default_and_reset(reset_fn, 5);
let mut component = pool.acquire();
component.value = 42;
component.name = "test".to_string();
pool.release(component);
let component2 = pool.acquire();
assert_eq!(component2.value, 0);
assert_eq!(component2.name, "");
}
#[test]
fn test_component_pool_max_capacity() {
let mut pool = ComponentPool::<TestComponent>::with_default(2);
// 获取3个组件
let comp1 = pool.acquire();
let comp2 = pool.acquire();
let comp3 = pool.acquire();
// 释放所有组件
pool.release(comp1);
pool.release(comp2);
pool.release(comp3);
// 只有2个组件被存储在池中最大容量限制
assert_eq!(pool.available_count(), 2);
}
#[test]
fn test_component_pool_prewarm() {
let mut pool = ComponentPool::<TestComponent>::with_default(10);
pool.prewarm(5);
assert_eq!(pool.available_count(), 5);
// 预热不应该超过最大容量
pool.prewarm(10);
assert_eq!(pool.available_count(), 10);
}
#[test]
fn test_component_pool_stats() {
let mut pool = ComponentPool::<TestComponent>::with_default(5);
// 获取一些组件
let _comp1 = pool.acquire();
let _comp2 = pool.acquire();
let stats = pool.get_stats();
assert_eq!(stats.total_acquires, 2);
assert_eq!(stats.pool_misses, 2);
assert_eq!(stats.pool_hits, 0);
assert_eq!(stats.total_created, 2);
}
#[test]
fn test_component_pool_manager_basic() {
let mut manager = ComponentPoolManager::new();
// 注册池
manager.register_pool_default::<TestComponent>(TypeId::of::<TestComponent>(), Some(20));
assert!(manager.has_pool(TypeId::of::<TestComponent>()));
assert_eq!(manager.pool_count(), 1);
}
#[test]
fn test_component_pool_manager_acquire_release() {
let mut manager = ComponentPoolManager::new();
manager.register_pool_default::<TestComponent>(TypeId::of::<TestComponent>(), Some(10));
// 获取组件
let mut component = manager.acquire_component::<TestComponent>(TypeId::of::<TestComponent>()).unwrap();
component.value = 42;
// 释放组件
manager.release_component(TypeId::of::<TestComponent>(), component);
// 再次获取应该从池中获取
let reused_component = manager.acquire_component::<TestComponent>(TypeId::of::<TestComponent>()).unwrap();
assert_eq!(reused_component.value, 42);
}
#[test]
fn test_component_pool_manager_multiple_types() {
let mut manager = ComponentPoolManager::new();
manager.register_pool_default::<TestComponent>(TypeId::of::<TestComponent>(), Some(10));
manager.register_pool_default::<AnotherTestComponent>(TypeId::of::<AnotherTestComponent>(), Some(15));
assert_eq!(manager.pool_count(), 2);
// 测试不同类型的组件
let _test_comp = manager.acquire_component::<TestComponent>(TypeId::of::<TestComponent>()).unwrap();
let _another_comp = manager.acquire_component::<AnotherTestComponent>(TypeId::of::<AnotherTestComponent>()).unwrap();
}
#[test]
fn test_component_pool_manager_stats() {
let mut manager = ComponentPoolManager::new();
manager.register_pool_default::<TestComponent>(TypeId::of::<TestComponent>(), Some(10));
manager.prewarm_pool(TypeId::of::<TestComponent>(), 5);
let stats = manager.get_pool_stats();
let test_comp_stats = stats.get(&TypeId::of::<TestComponent>()).unwrap();
assert_eq!(test_comp_stats.available, 5);
assert_eq!(test_comp_stats.max_size, 10);
assert!(test_comp_stats.memory_usage > 0);
}
#[test]
fn test_component_pool_manager_prewarm_and_clear() {
let mut manager = ComponentPoolManager::new();
manager.register_pool_default::<TestComponent>(TypeId::of::<TestComponent>(), Some(10));
manager.register_pool_default::<AnotherTestComponent>(TypeId::of::<AnotherTestComponent>(), Some(10));
// 预热所有池
manager.prewarm_all(5);
let stats = manager.get_pool_stats();
assert_eq!(stats.get(&TypeId::of::<TestComponent>()).unwrap().available, 5);
assert_eq!(stats.get(&TypeId::of::<AnotherTestComponent>()).unwrap().available, 5);
// 清空所有池
manager.clear_all();
let stats = manager.get_pool_stats();
assert_eq!(stats.get(&TypeId::of::<TestComponent>()).unwrap().available, 0);
assert_eq!(stats.get(&TypeId::of::<AnotherTestComponent>()).unwrap().available, 0);
}
#[test]
fn test_component_pool_manager_unknown_type() {
let mut manager = ComponentPoolManager::new();
// 尝试获取未注册类型的组件
let result = manager.acquire_component::<TestComponent>(TypeId::of::<TestComponent>());
assert!(result.is_none());
// 释放到未注册的池应该安全处理
let component = TestComponent::default();
manager.release_component(TypeId::of::<TestComponent>(), component); // 不应该panic
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,896 @@
use crate::utils::ComponentType;
use rustc_hash::FxHashMap;
use std::collections::HashSet;
/**
* 脏标记类型
* 使用位标记来表示不同类型的变更
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DirtyFlag(pub u32);
impl DirtyFlag {
/// 组件数据已修改
pub const COMPONENT_MODIFIED: DirtyFlag = DirtyFlag(1 << 0);
/// 组件已添加
pub const COMPONENT_ADDED: DirtyFlag = DirtyFlag(1 << 1);
/// 组件已移除
pub const COMPONENT_REMOVED: DirtyFlag = DirtyFlag(1 << 2);
/// 实体位置已改变
pub const TRANSFORM_CHANGED: DirtyFlag = DirtyFlag(1 << 3);
/// 实体状态已改变
pub const STATE_CHANGED: DirtyFlag = DirtyFlag(1 << 4);
/// 实体层次结构已改变
pub const HIERARCHY_CHANGED: DirtyFlag = DirtyFlag(1 << 5);
/// 实体可见性已改变
pub const VISIBILITY_CHANGED: DirtyFlag = DirtyFlag(1 << 6);
/// 实体启用状态已改变
pub const ENABLED_CHANGED: DirtyFlag = DirtyFlag(1 << 7);
/// 自定义标记1
pub const CUSTOM_1: DirtyFlag = DirtyFlag(1 << 8);
/// 自定义标记2
pub const CUSTOM_2: DirtyFlag = DirtyFlag(1 << 9);
/// 自定义标记3
pub const CUSTOM_3: DirtyFlag = DirtyFlag(1 << 10);
/// 自定义标记4
pub const CUSTOM_4: DirtyFlag = DirtyFlag(1 << 11);
/// 所有标记
pub const ALL: DirtyFlag = DirtyFlag(0xFFFFFFFF);
/**
* 检查是否包含指定标记
*/
pub fn contains(self, other: DirtyFlag) -> bool {
(self.0 & other.0) != 0
}
/**
* 添加标记
*/
pub fn add(&mut self, other: DirtyFlag) {
self.0 |= other.0;
}
/**
* 移除标记
*/
pub fn remove(&mut self, other: DirtyFlag) {
self.0 &= !other.0;
}
/**
* 清空所有标记
*/
pub fn clear(&mut self) {
self.0 = 0;
}
/**
* 检查是否为空
*/
pub fn is_empty(self) -> bool {
self.0 == 0
}
/**
* 与操作
*/
pub fn and(self, other: DirtyFlag) -> DirtyFlag {
DirtyFlag(self.0 & other.0)
}
/**
* 或操作
*/
pub fn or(self, other: DirtyFlag) -> DirtyFlag {
DirtyFlag(self.0 | other.0)
}
}
impl std::ops::BitOr for DirtyFlag {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
DirtyFlag(self.0 | rhs.0)
}
}
impl std::ops::BitAnd for DirtyFlag {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
DirtyFlag(self.0 & rhs.0)
}
}
impl std::ops::BitOrAssign for DirtyFlag {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAndAssign for DirtyFlag {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
/**
* 脏标记数据
* 记录实体的变更信息
*/
#[derive(Debug, Clone)]
pub struct DirtyData {
/// 实体ID
pub entity_id: u32,
/// 脏标记位
pub flags: DirtyFlag,
/// 修改的组件类型列表
pub modified_components: HashSet<ComponentType>,
/// 标记时间戳(毫秒)
pub timestamp: u64,
/// 帧编号
pub frame_number: u64,
}
impl DirtyData {
/**
* 创建新的脏标记数据
*/
pub fn new(entity_id: u32, flags: DirtyFlag, frame_number: u64) -> Self {
Self {
entity_id,
flags,
modified_components: HashSet::new(),
timestamp: current_timestamp(),
frame_number,
}
}
/**
* 添加修改的组件类型
*/
pub fn add_modified_component(&mut self, component_type: ComponentType) {
self.modified_components.insert(component_type);
}
/**
* 检查是否包含指定的脏标记
*/
pub fn has_flags(&self, flags: DirtyFlag) -> bool {
self.flags.contains(flags)
}
/**
* 更新时间戳
*/
pub fn update_timestamp(&mut self) {
self.timestamp = current_timestamp();
}
/**
* 获取年龄(当前时间与标记时间的差值,毫秒)
*/
pub fn age(&self) -> u64 {
current_timestamp().saturating_sub(self.timestamp)
}
}
/**
* 脏标记监听器类型
*/
pub type DirtyListener = Box<dyn Fn(&DirtyData) + Send + Sync>;
/**
* 脏标记监听器配置
*/
#[derive(Debug)]
pub struct DirtyListenerConfig {
/// 感兴趣的标记类型
pub flags: DirtyFlag,
/// 监听器优先级(数字越小优先级越高)
pub priority: i32,
/// 监听器ID用于移除
pub id: u64,
}
/**
* 脏标记监听器条目
*/
pub struct DirtyListenerEntry {
pub config: DirtyListenerConfig,
pub callback: DirtyListener,
}
/**
* 脏标记统计信息
*/
#[derive(Debug, Clone)]
pub struct DirtyTrackingStats {
/// 当前脏实体数量
pub dirty_entity_count: usize,
/// 总标记次数
pub total_markings: u64,
/// 总清理次数
pub total_cleanups: u64,
/// 监听器数量
pub listener_count: usize,
/// 当前帧编号
pub current_frame: u64,
/// 平均每帧脏实体数量
pub avg_dirty_per_frame: f64,
/// 处理的实体总数
pub total_processed_entities: u64,
/// 内存使用量估算(字节)
pub estimated_memory_usage: usize,
/// 最大处理时间(毫秒)
pub max_processing_time: f64,
/// 平均处理时间(毫秒)
pub avg_processing_time: f64,
}
impl Default for DirtyTrackingStats {
fn default() -> Self {
Self {
dirty_entity_count: 0,
total_markings: 0,
total_cleanups: 0,
listener_count: 0,
current_frame: 0,
avg_dirty_per_frame: 0.0,
total_processed_entities: 0,
estimated_memory_usage: 0,
max_processing_time: 0.0,
avg_processing_time: 0.0,
}
}
}
/**
* 脏标记追踪系统
*
* 提供高效的组件和实体变更追踪,避免不必要的计算和更新。
* 支持细粒度的脏标记和批量处理机制。
*/
pub struct DirtyTrackingSystem {
/// 脏实体映射表
dirty_entities: FxHashMap<u32, DirtyData>,
/// 脏标记监听器
listeners: Vec<DirtyListenerEntry>,
/// 下一个监听器ID
next_listener_id: u64,
/// 当前帧编号
current_frame: u64,
/// 批处理配置
batch_size: usize,
max_processing_time_ms: f64,
/// 处理队列
processing_queue: Vec<DirtyData>,
is_processing: bool,
/// 统计信息
stats: DirtyTrackingStats,
/// 帧统计累积
frame_stats: FrameStats,
/// 处理时间记录
processing_times: Vec<f64>,
max_processing_time_history: usize,
}
/**
* 帧统计信息累积
*/
#[derive(Debug, Default)]
struct FrameStats {
total_dirty_entities: u64,
frame_count: u64,
total_processing_time: f64,
}
impl DirtyTrackingSystem {
/**
* 创建新的脏标记追踪系统
*/
pub fn new() -> Self {
Self {
dirty_entities: FxHashMap::default(),
listeners: Vec::new(),
next_listener_id: 1,
current_frame: 0,
batch_size: 100,
max_processing_time_ms: 16.0,
processing_queue: Vec::new(),
is_processing: false,
stats: DirtyTrackingStats::default(),
frame_stats: FrameStats::default(),
processing_times: Vec::new(),
max_processing_time_history: 100,
}
}
/**
* 标记实体为脏状态
*/
pub fn mark_dirty(
&mut self,
entity_id: u32,
flags: DirtyFlag,
modified_components: Option<Vec<ComponentType>>
) {
self.stats.total_markings += 1;
let dirty_data = self.dirty_entities.entry(entity_id).or_insert_with(|| {
DirtyData::new(entity_id, DirtyFlag(0), self.current_frame)
});
dirty_data.flags |= flags;
dirty_data.update_timestamp();
dirty_data.frame_number = self.current_frame;
if let Some(components) = modified_components {
for component_type in components {
dirty_data.add_modified_component(component_type);
}
}
// 克隆dirty_data以避免借用冲突
let dirty_data_for_notify = dirty_data.clone();
// 立即通知监听器
self.notify_listeners(&dirty_data_for_notify, flags);
}
/**
* 检查实体是否有指定的脏标记
*/
pub fn is_dirty(&self, entity_id: u32, flags: DirtyFlag) -> bool {
self.dirty_entities
.get(&entity_id)
.map(|data| data.has_flags(flags))
.unwrap_or(false)
}
/**
* 清除实体的脏标记
*/
pub fn clear_dirty(&mut self, entity_id: u32, flags: DirtyFlag) {
if let Some(dirty_data) = self.dirty_entities.get_mut(&entity_id) {
dirty_data.flags.remove(flags);
if dirty_data.flags.is_empty() {
self.dirty_entities.remove(&entity_id);
}
self.stats.total_cleanups += 1;
}
}
/**
* 清除所有脏标记
*/
pub fn clear_all_dirty(&mut self) {
let count = self.dirty_entities.len();
self.dirty_entities.clear();
self.stats.total_cleanups += count as u64;
}
/**
* 获取所有脏实体
*/
pub fn get_dirty_entities(&self, flags: DirtyFlag) -> Vec<&DirtyData> {
self.dirty_entities
.values()
.filter(|data| data.has_flags(flags))
.collect()
}
/**
* 获取脏实体数量
*/
pub fn dirty_entity_count(&self) -> usize {
self.dirty_entities.len()
}
/**
* 获取指定标记的脏实体数量
*/
pub fn dirty_entity_count_with_flags(&self, flags: DirtyFlag) -> usize {
self.dirty_entities
.values()
.filter(|data| data.has_flags(flags))
.count()
}
/**
* 批量处理脏实体
*/
pub fn process_dirty_entities(&mut self) {
if self.is_processing {
return;
}
self.is_processing = true;
let start_time = current_timestamp_f64();
// 填充处理队列
if self.processing_queue.is_empty() {
self.processing_queue.extend(
self.dirty_entities.values().cloned()
);
}
let mut processed = 0;
while !self.processing_queue.is_empty() && processed < self.batch_size {
let elapsed = current_timestamp_f64() - start_time;
if elapsed > self.max_processing_time_ms {
break;
}
if let Some(dirty_data) = self.processing_queue.pop() {
self.process_entity(&dirty_data);
processed += 1;
}
}
// 如果处理完成,更新统计信息
if self.processing_queue.is_empty() {
self.is_processing = false;
let processing_time = current_timestamp_f64() - start_time;
self.record_processing_time(processing_time);
self.stats.total_processed_entities += processed as u64;
}
}
/**
* 添加脏标记监听器
*/
pub fn add_listener<F>(&mut self, flags: DirtyFlag, priority: i32, callback: F) -> u64
where
F: Fn(&DirtyData) + Send + Sync + 'static,
{
let listener_id = self.next_listener_id;
self.next_listener_id += 1;
let config = DirtyListenerConfig {
flags,
priority,
id: listener_id,
};
let entry = DirtyListenerEntry {
config,
callback: Box::new(callback),
};
self.listeners.push(entry);
// 按优先级排序
self.listeners.sort_by_key(|entry| entry.config.priority);
listener_id
}
/**
* 移除脏标记监听器
*/
pub fn remove_listener(&mut self, listener_id: u64) -> bool {
if let Some(pos) = self.listeners.iter().position(|entry| entry.config.id == listener_id) {
self.listeners.remove(pos);
true
} else {
false
}
}
/**
* 开始新的帧
*/
pub fn begin_frame(&mut self) {
self.current_frame += 1;
self.stats.current_frame = self.current_frame;
}
/**
* 结束当前帧
*/
pub fn end_frame(&mut self) {
if !self.is_processing {
self.process_dirty_entities();
}
// 更新帧统计
self.frame_stats.total_dirty_entities += self.dirty_entities.len() as u64;
self.frame_stats.frame_count += 1;
// 更新平均值
if self.frame_stats.frame_count > 0 {
self.stats.avg_dirty_per_frame =
self.frame_stats.total_dirty_entities as f64 / self.frame_stats.frame_count as f64;
}
}
/**
* 获取统计信息
*/
pub fn get_stats(&self) -> DirtyTrackingStats {
let mut stats = self.stats.clone();
stats.dirty_entity_count = self.dirty_entities.len();
stats.listener_count = self.listeners.len();
stats.estimated_memory_usage = self.estimate_memory_usage();
// 计算平均处理时间
if !self.processing_times.is_empty() {
let total_time: f64 = self.processing_times.iter().sum();
stats.avg_processing_time = total_time / self.processing_times.len() as f64;
}
stats
}
/**
* 配置批量处理参数
*/
pub fn configure_batch_processing(&mut self, batch_size: usize, max_processing_time_ms: f64) {
self.batch_size = batch_size;
self.max_processing_time_ms = max_processing_time_ms;
}
/**
* 清空所有数据
*/
pub fn clear(&mut self) {
self.dirty_entities.clear();
self.processing_queue.clear();
self.is_processing = false;
self.stats = DirtyTrackingStats::default();
self.frame_stats = FrameStats::default();
self.processing_times.clear();
}
/**
* 获取老旧的脏标记(超过指定时间未更新)
*/
pub fn get_stale_dirty_entities(&self, max_age_ms: u64) -> Vec<&DirtyData> {
self.dirty_entities
.values()
.filter(|data| data.age() > max_age_ms)
.collect()
}
/**
* 清理老旧的脏标记
*/
pub fn cleanup_stale_dirty_entities(&mut self, max_age_ms: u64) -> usize {
let initial_count = self.dirty_entities.len();
self.dirty_entities.retain(|_, data| data.age() <= max_age_ms);
let removed_count = initial_count - self.dirty_entities.len();
self.stats.total_cleanups += removed_count as u64;
removed_count
}
// 私有方法
/**
* 处理单个脏实体
*/
fn process_entity(&mut self, dirty_data: &DirtyData) {
for entry in &self.listeners {
if dirty_data.has_flags(entry.config.flags) {
(entry.callback)(dirty_data);
}
}
// 处理后清理
self.clear_dirty(dirty_data.entity_id, DirtyFlag::ALL);
}
/**
* 通知监听器
*/
fn notify_listeners(&self, dirty_data: &DirtyData, new_flags: DirtyFlag) {
for entry in &self.listeners {
if new_flags.contains(entry.config.flags) {
(entry.callback)(dirty_data);
}
}
}
/**
* 记录处理时间
*/
fn record_processing_time(&mut self, time: f64) {
self.processing_times.push(time);
// 保持历史记录长度限制
if self.processing_times.len() > self.max_processing_time_history {
self.processing_times.remove(0);
}
// 更新最大处理时间
if time > self.stats.max_processing_time {
self.stats.max_processing_time = time;
}
self.frame_stats.total_processing_time += time;
}
/**
* 估算内存使用量
*/
fn estimate_memory_usage(&self) -> usize {
let dirty_entities_size = self.dirty_entities.len() *
(std::mem::size_of::<u32>() + std::mem::size_of::<DirtyData>());
let listeners_size = self.listeners.len() * std::mem::size_of::<DirtyListenerEntry>();
let processing_queue_size = self.processing_queue.len() * std::mem::size_of::<DirtyData>();
let processing_times_size = self.processing_times.len() * std::mem::size_of::<f64>();
dirty_entities_size + listeners_size + processing_queue_size + processing_times_size
}
}
impl Default for DirtyTrackingSystem {
fn default() -> Self {
Self::new()
}
}
// 辅助函数
/**
* 获取当前时间戳(毫秒)
*/
fn current_timestamp() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
/**
* 获取当前时间戳(浮点毫秒,用于精确计时)
*/
fn current_timestamp_f64() -> f64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs_f64() * 1000.0
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::TypeId;
use std::sync::{Arc, Mutex};
#[test]
fn test_dirty_flag_operations() {
let mut flags = DirtyFlag::COMPONENT_MODIFIED;
assert!(flags.contains(DirtyFlag::COMPONENT_MODIFIED));
assert!(!flags.contains(DirtyFlag::COMPONENT_ADDED));
flags.add(DirtyFlag::COMPONENT_ADDED);
assert!(flags.contains(DirtyFlag::COMPONENT_MODIFIED));
assert!(flags.contains(DirtyFlag::COMPONENT_ADDED));
flags.remove(DirtyFlag::COMPONENT_MODIFIED);
assert!(!flags.contains(DirtyFlag::COMPONENT_MODIFIED));
assert!(flags.contains(DirtyFlag::COMPONENT_ADDED));
flags.clear();
assert!(flags.is_empty());
}
#[test]
fn test_dirty_flag_bitwise_operations() {
let flag1 = DirtyFlag::COMPONENT_MODIFIED;
let flag2 = DirtyFlag::COMPONENT_ADDED;
let combined = flag1 | flag2;
assert!(combined.contains(DirtyFlag::COMPONENT_MODIFIED));
assert!(combined.contains(DirtyFlag::COMPONENT_ADDED));
let intersection = combined & DirtyFlag::COMPONENT_MODIFIED;
assert!(intersection.contains(DirtyFlag::COMPONENT_MODIFIED));
assert!(!intersection.contains(DirtyFlag::COMPONENT_ADDED));
}
#[test]
fn test_dirty_data_creation() {
let entity_id = 123;
let flags = DirtyFlag::TRANSFORM_CHANGED;
let frame_number = 42;
let dirty_data = DirtyData::new(entity_id, flags, frame_number);
assert_eq!(dirty_data.entity_id, entity_id);
assert!(dirty_data.has_flags(flags));
assert_eq!(dirty_data.frame_number, frame_number);
assert!(dirty_data.modified_components.is_empty());
}
#[test]
fn test_dirty_data_component_tracking() {
let mut dirty_data = DirtyData::new(1, DirtyFlag::COMPONENT_MODIFIED, 0);
let component_type = TypeId::of::<String>();
dirty_data.add_modified_component(component_type);
assert!(dirty_data.modified_components.contains(&component_type));
}
#[test]
fn test_dirty_tracking_basic() {
let mut system = DirtyTrackingSystem::new();
let entity_id = 1;
let flags = DirtyFlag::COMPONENT_MODIFIED;
// 标记实体为脏状态
system.mark_dirty(entity_id, flags, None);
assert!(system.is_dirty(entity_id, flags));
assert!(!system.is_dirty(entity_id, DirtyFlag::COMPONENT_ADDED));
assert_eq!(system.dirty_entity_count(), 1);
// 清除脏标记
system.clear_dirty(entity_id, flags);
assert!(!system.is_dirty(entity_id, flags));
assert_eq!(system.dirty_entity_count(), 0);
}
#[test]
fn test_dirty_tracking_multiple_flags() {
let mut system = DirtyTrackingSystem::new();
let entity_id = 1;
// 标记多个类型的脏状态
system.mark_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED, None);
system.mark_dirty(entity_id, DirtyFlag::TRANSFORM_CHANGED, None);
assert!(system.is_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED));
assert!(system.is_dirty(entity_id, DirtyFlag::TRANSFORM_CHANGED));
assert!(system.is_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED | DirtyFlag::TRANSFORM_CHANGED));
// 部分清除
system.clear_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED);
assert!(!system.is_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED));
assert!(system.is_dirty(entity_id, DirtyFlag::TRANSFORM_CHANGED));
// 全部清除
system.clear_dirty(entity_id, DirtyFlag::ALL);
assert!(!system.is_dirty(entity_id, DirtyFlag::TRANSFORM_CHANGED));
}
#[test]
fn test_dirty_tracking_listener() {
let mut system = DirtyTrackingSystem::new();
let entity_id = 1;
// 使用Arc<Mutex>来在闭包中共享状态
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
// 添加监听器
let listener_id = system.add_listener(
DirtyFlag::COMPONENT_MODIFIED,
0,
move |_data| {
*callback_count_clone.lock().unwrap() += 1;
}
);
// 标记脏状态应该触发监听器
system.mark_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED, None);
assert_eq!(*callback_count.lock().unwrap(), 1);
// 标记其他类型的脏状态不应该触发监听器
system.mark_dirty(entity_id, DirtyFlag::TRANSFORM_CHANGED, None);
assert_eq!(*callback_count.lock().unwrap(), 1);
// 移除监听器
assert!(system.remove_listener(listener_id));
// 再次标记脏状态不应该触发监听器
system.mark_dirty(entity_id, DirtyFlag::COMPONENT_MODIFIED, None);
assert_eq!(*callback_count.lock().unwrap(), 1);
}
#[test]
fn test_dirty_tracking_filtering() {
let mut system = DirtyTrackingSystem::new();
system.mark_dirty(1, DirtyFlag::COMPONENT_MODIFIED, None);
system.mark_dirty(2, DirtyFlag::TRANSFORM_CHANGED, None);
system.mark_dirty(3, DirtyFlag::COMPONENT_MODIFIED | DirtyFlag::TRANSFORM_CHANGED, None);
// 获取包含组件修改标记的实体
let component_modified = system.get_dirty_entities(DirtyFlag::COMPONENT_MODIFIED);
assert_eq!(component_modified.len(), 2); // 实体1和3
// 获取包含变换修改标记的实体
let transform_changed = system.get_dirty_entities(DirtyFlag::TRANSFORM_CHANGED);
assert_eq!(transform_changed.len(), 2); // 实体2和3
// 获取包含两种标记的实体
let both_flags = system.get_dirty_entities(DirtyFlag::COMPONENT_MODIFIED | DirtyFlag::TRANSFORM_CHANGED);
assert_eq!(both_flags.len(), 3); // 所有实体
}
#[test]
fn test_dirty_tracking_stats() {
let mut system = DirtyTrackingSystem::new();
system.mark_dirty(1, DirtyFlag::COMPONENT_MODIFIED, None);
system.mark_dirty(2, DirtyFlag::TRANSFORM_CHANGED, None);
system.clear_dirty(1, DirtyFlag::ALL);
let stats = system.get_stats();
assert_eq!(stats.total_markings, 2);
assert_eq!(stats.total_cleanups, 1);
assert_eq!(stats.dirty_entity_count, 1);
}
#[test]
fn test_dirty_tracking_stale_cleanup() {
let mut system = DirtyTrackingSystem::new();
system.mark_dirty(1, DirtyFlag::COMPONENT_MODIFIED, None);
system.mark_dirty(2, DirtyFlag::TRANSFORM_CHANGED, None);
// 等待一小段时间让标记变老
std::thread::sleep(std::time::Duration::from_millis(10));
// 清理超过5毫秒的老标记
let removed_count = system.cleanup_stale_dirty_entities(5);
assert_eq!(removed_count, 2);
assert_eq!(system.dirty_entity_count(), 0);
}
#[test]
fn test_dirty_tracking_frame_management() {
let mut system = DirtyTrackingSystem::new();
system.begin_frame();
assert_eq!(system.get_stats().current_frame, 1);
system.mark_dirty(1, DirtyFlag::COMPONENT_MODIFIED, None);
system.end_frame();
let stats = system.get_stats();
assert_eq!(stats.current_frame, 1);
}
#[test]
fn test_dirty_tracking_batch_configuration() {
let mut system = DirtyTrackingSystem::new();
system.configure_batch_processing(50, 8.0);
assert_eq!(system.batch_size, 50);
assert_eq!(system.max_processing_time_ms, 8.0);
}
#[test]
fn test_dirty_tracking_clear() {
let mut system = DirtyTrackingSystem::new();
system.mark_dirty(1, DirtyFlag::COMPONENT_MODIFIED, None);
system.mark_dirty(2, DirtyFlag::TRANSFORM_CHANGED, None);
let _listener_id = system.add_listener(DirtyFlag::ALL, 0, |_| {});
assert_eq!(system.dirty_entity_count(), 2);
assert_eq!(system.listeners.len(), 1);
system.clear();
assert_eq!(system.dirty_entity_count(), 0);
// 注意clear()不会清除监听器
assert_eq!(system.listeners.len(), 1);
assert_eq!(system.get_stats().total_markings, 0);
}
}

View File

@@ -0,0 +1,818 @@
use std::any::{Any, TypeId};
use std::fmt::Debug;
/**
* 数字扩展工具
* 提供数字转换和处理的实用方法
*/
pub struct NumberExtension;
impl NumberExtension {
/**
* 将Option<T>转换为数字如果值为None则返回0
*/
pub fn to_number_from_option<T>(value: Option<T>) -> f64
where
T: Into<f64>,
{
value.map(|v| v.into()).unwrap_or(0.0)
}
/**
* 将字符串转换为数字,如果解析失败则返回默认值
*/
pub fn parse_or_default(value: &str, default: f64) -> f64 {
value.parse::<f64>().unwrap_or(default)
}
/**
* 将字符串转换为数字如果解析失败则返回0
*/
pub fn parse_or_zero(value: &str) -> f64 {
Self::parse_or_default(value, 0.0)
}
/**
* 将字符串转换为整数,如果解析失败则返回默认值
*/
pub fn parse_int_or_default(value: &str, default: i64) -> i64 {
value.parse::<i64>().unwrap_or(default)
}
/**
* 将字符串转换为整数如果解析失败则返回0
*/
pub fn parse_int_or_zero(value: &str) -> i64 {
Self::parse_int_or_default(value, 0)
}
/**
* 将布尔值转换为数字
*/
pub fn bool_to_number(value: bool) -> f64 {
if value { 1.0 } else { 0.0 }
}
/**
* 将数字转换为布尔值
*/
pub fn number_to_bool(value: f64) -> bool {
value != 0.0
}
/**
* 限制数字在指定范围内
*/
pub fn clamp(value: f64, min: f64, max: f64) -> f64 {
if value < min {
min
} else if value > max {
max
} else {
value
}
}
/**
* 检查数字是否在指定范围内
*/
pub fn is_in_range(value: f64, min: f64, max: f64) -> bool {
value >= min && value <= max
}
/**
* 四舍五入到指定小数位数
*/
pub fn round_to_decimal_places(value: f64, decimal_places: u32) -> f64 {
let multiplier = 10_f64.powi(decimal_places as i32);
(value * multiplier).round() / multiplier
}
/**
* 将弧度转换为角度
*/
pub fn radians_to_degrees(radians: f64) -> f64 {
radians * 180.0 / std::f64::consts::PI
}
/**
* 将角度转换为弧度
*/
pub fn degrees_to_radians(degrees: f64) -> f64 {
degrees * std::f64::consts::PI / 180.0
}
/**
* 线性插值
*/
pub fn lerp(from: f64, to: f64, t: f64) -> f64 {
from + (to - from) * t
}
/**
* 反向线性插值返回t值
*/
pub fn inverse_lerp(from: f64, to: f64, value: f64) -> f64 {
if (to - from).abs() < f64::EPSILON {
0.0
} else {
(value - from) / (to - from)
}
}
/**
* 计算两个数字之间的距离
*/
pub fn distance(a: f64, b: f64) -> f64 {
(a - b).abs()
}
/**
* 检查两个浮点数是否近似相等
*/
pub fn approximately_equal(a: f64, b: f64, epsilon: Option<f64>) -> bool {
let eps = epsilon.unwrap_or(f64::EPSILON);
(a - b).abs() < eps
}
/**
* 将值包装在0到max之间循环
*/
pub fn wrap(value: f64, max: f64) -> f64 {
if max <= 0.0 {
return 0.0;
}
let mut result = value % max;
if result < 0.0 {
result += max;
}
result
}
/**
* 计算数字的符号(-1, 0, 1
*/
pub fn sign(value: f64) -> f64 {
if value > 0.0 {
1.0
} else if value < 0.0 {
-1.0
} else {
0.0
}
}
}
/**
* 类型工具
* 提供类型相关的实用方法
*/
pub struct TypeUtils;
impl TypeUtils {
/**
* 获取类型的TypeId
*/
pub fn get_type_id<T: 'static>() -> TypeId {
TypeId::of::<T>()
}
/**
* 获取对象的TypeId
*/
pub fn get_object_type_id<T: 'static>(_obj: &T) -> TypeId {
TypeId::of::<T>()
}
/**
* 获取类型名称
*/
pub fn get_type_name<T: 'static>() -> &'static str {
std::any::type_name::<T>()
}
/**
* 获取对象的类型名称
*/
pub fn get_object_type_name<T: 'static>(_obj: &T) -> &'static str {
std::any::type_name::<T>()
}
/**
* 检查两个类型是否相同
*/
pub fn is_same_type<T: 'static, U: 'static>() -> bool {
TypeId::of::<T>() == TypeId::of::<U>()
}
/**
* 检查对象是否为指定类型
*/
pub fn is_type<T: 'static, U: 'static>(_obj: &T) -> bool {
TypeId::of::<T>() == TypeId::of::<U>()
}
/**
* 尝试将Any trait对象转换为具体类型
*/
pub fn downcast_ref<T: 'static>(obj: &dyn Any) -> Option<&T> {
obj.downcast_ref::<T>()
}
/**
* 尝试将可变Any trait对象转换为具体类型
*/
pub fn downcast_mut<T: 'static>(obj: &mut dyn Any) -> Option<&mut T> {
obj.downcast_mut::<T>()
}
/**
* 检查是否可以转换为指定类型
*/
pub fn can_downcast<T: 'static>(obj: &dyn Any) -> bool {
obj.is::<T>()
}
/**
* 获取类型的大小(字节)
*/
pub fn get_type_size<T>() -> usize {
std::mem::size_of::<T>()
}
/**
* 获取对象的大小(字节)
*/
pub fn get_object_size<T>(obj: &T) -> usize {
std::mem::size_of_val(obj)
}
/**
* 检查类型是否为零大小类型
*/
pub fn is_zero_sized<T>() -> bool {
std::mem::size_of::<T>() == 0
}
/**
* 获取类型的对齐要求
*/
pub fn get_type_align<T>() -> usize {
std::mem::align_of::<T>()
}
/**
* 检查类型是否实现了Copy trait通过编译时检查
*/
pub fn is_copy_type<T: Copy>() -> bool {
true
}
/**
* 检查类型是否实现了Clone trait通过编译时检查
*/
pub fn is_clone_type<T: Clone>() -> bool {
true
}
/**
* 检查类型是否实现了Debug trait通过编译时检查
*/
pub fn is_debug_type<T: Debug>() -> bool {
true
}
/**
* 安全地克隆对象如果实现了Clone
*/
pub fn safe_clone<T: Clone>(obj: &T) -> T {
obj.clone()
}
/**
* 获取类型的显示字符串如果实现了Debug
*/
pub fn debug_string<T: Debug>(obj: &T) -> String {
format!("{:?}", obj)
}
}
/**
* 字符串扩展工具
* 提供字符串处理的实用方法
*/
pub struct StringExtension;
impl StringExtension {
/**
* 检查字符串是否为空或仅包含空白字符
*/
pub fn is_null_or_whitespace(s: Option<&str>) -> bool {
match s {
None => true,
Some(s) => s.trim().is_empty(),
}
}
/**
* 检查字符串是否为空
*/
pub fn is_null_or_empty(s: Option<&str>) -> bool {
match s {
None => true,
Some(s) => s.is_empty(),
}
}
/**
* 截断字符串到指定长度
*/
pub fn truncate(s: &str, max_length: usize) -> String {
if s.len() <= max_length {
s.to_string()
} else {
let mut truncated = String::with_capacity(max_length + 3);
truncated.push_str(&s[..max_length]);
truncated.push_str("...");
truncated
}
}
/**
* 将字符串转换为Pascal命名
*/
pub fn to_pascal_case(s: &str) -> String {
s.split_whitespace()
.map(|word| {
let mut chars = word.chars();
match chars.next() {
None => String::new(),
Some(first) => first.to_uppercase().collect::<String>() + &chars.as_str().to_lowercase(),
}
})
.collect::<Vec<String>>()
.join("")
}
/**
* 将字符串转换为camel命名
*/
pub fn to_camel_case(s: &str) -> String {
let pascal = Self::to_pascal_case(s);
if pascal.is_empty() {
return pascal;
}
let mut chars = pascal.chars();
match chars.next() {
None => String::new(),
Some(first) => first.to_lowercase().collect::<String>() + chars.as_str(),
}
}
/**
* 将字符串转换为snake_case
*/
pub fn to_snake_case(s: &str) -> String {
s.chars()
.enumerate()
.flat_map(|(i, c)| {
if i > 0 && c.is_uppercase() {
vec!['_', c.to_lowercase().next().unwrap()]
} else {
vec![c.to_lowercase().next().unwrap()]
}
})
.collect()
}
/**
* 重复字符串指定次数
*/
pub fn repeat(s: &str, count: usize) -> String {
s.repeat(count)
}
/**
* 左侧填充字符到指定长度
*/
pub fn pad_left(s: &str, total_width: usize, pad_char: char) -> String {
if s.len() >= total_width {
s.to_string()
} else {
let pad_count = total_width - s.len();
pad_char.to_string().repeat(pad_count) + s
}
}
/**
* 右侧填充字符到指定长度
*/
pub fn pad_right(s: &str, total_width: usize, pad_char: char) -> String {
if s.len() >= total_width {
s.to_string()
} else {
let pad_count = total_width - s.len();
s.to_string() + &pad_char.to_string().repeat(pad_count)
}
}
/**
* 反转字符串
*/
pub fn reverse(s: &str) -> String {
s.chars().rev().collect()
}
/**
* 统计子字符串出现次数
*/
pub fn count_occurrences(s: &str, pattern: &str) -> usize {
if pattern.is_empty() {
return 0;
}
let mut count = 0;
let mut start = 0;
while let Some(pos) = s[start..].find(pattern) {
count += 1;
start += pos + pattern.len();
}
count
}
/**
* 移除字符串中的所有空白字符
*/
pub fn remove_whitespace(s: &str) -> String {
s.chars().filter(|c| !c.is_whitespace()).collect()
}
}
/**
* 集合扩展工具
* 提供集合操作的实用方法
*/
pub struct CollectionExtension;
impl CollectionExtension {
/**
* 检查Vector是否为空或None
*/
pub fn is_null_or_empty<T>(vec: Option<&Vec<T>>) -> bool {
match vec {
None => true,
Some(v) => v.is_empty(),
}
}
/**
* 安全地获取Vector中指定索引的元素
*/
pub fn get_safe<T>(vec: &[T], index: usize) -> Option<&T> {
vec.get(index)
}
/**
* 查找满足条件的第一个元素
*/
pub fn find<T, F>(vec: &[T], predicate: F) -> Option<&T>
where
F: Fn(&T) -> bool,
{
vec.iter().find(|&item| predicate(item))
}
/**
* 查找满足条件的所有元素
*/
pub fn find_all<T, F>(vec: &[T], predicate: F) -> Vec<&T>
where
F: Fn(&T) -> bool,
{
vec.iter().filter(|&item| predicate(item)).collect()
}
/**
* 检查是否存在满足条件的元素
*/
pub fn exists<T, F>(vec: &[T], predicate: F) -> bool
where
F: Fn(&T) -> bool,
{
vec.iter().any(|item| predicate(item))
}
/**
* 检查所有元素是否都满足条件
*/
pub fn all<T, F>(vec: &[T], predicate: F) -> bool
where
F: Fn(&T) -> bool,
{
vec.iter().all(|item| predicate(item))
}
/**
* 获取Vector的最大值
*/
pub fn max<T: Ord + Clone>(vec: &[T]) -> Option<T> {
vec.iter().max().cloned()
}
/**
* 获取Vector的最小值
*/
pub fn min<T: Ord + Clone>(vec: &[T]) -> Option<T> {
vec.iter().min().cloned()
}
/**
* 计算数字Vector的和
*/
pub fn sum<T>(vec: &[T]) -> T
where
T: std::iter::Sum + Copy,
{
vec.iter().copied().sum()
}
/**
* 计算数字Vector的平均值
*/
pub fn average(vec: &[f64]) -> Option<f64> {
if vec.is_empty() {
None
} else {
Some(Self::sum(vec) / vec.len() as f64)
}
}
/**
* 去重Vector中的元素
*/
pub fn distinct<T: Eq + Clone>(vec: &[T]) -> Vec<T> {
let mut result = Vec::new();
for item in vec {
if !result.contains(item) {
result.push(item.clone());
}
}
result
}
/**
* 分块处理Vector
*/
pub fn chunk<T>(vec: &[T], size: usize) -> Vec<&[T]> {
if size == 0 {
return Vec::new();
}
vec.chunks(size).collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_number_extension_parse() {
assert_eq!(NumberExtension::parse_or_zero("123"), 123.0);
assert_eq!(NumberExtension::parse_or_zero("123.45"), 123.45);
assert_eq!(NumberExtension::parse_or_zero("invalid"), 0.0);
assert_eq!(NumberExtension::parse_or_default("invalid", 99.0), 99.0);
assert_eq!(NumberExtension::parse_int_or_zero("123"), 123);
assert_eq!(NumberExtension::parse_int_or_zero("invalid"), 0);
assert_eq!(NumberExtension::parse_int_or_default("invalid", 99), 99);
}
#[test]
fn test_number_extension_bool_conversion() {
assert_eq!(NumberExtension::bool_to_number(true), 1.0);
assert_eq!(NumberExtension::bool_to_number(false), 0.0);
assert_eq!(NumberExtension::number_to_bool(1.0), true);
assert_eq!(NumberExtension::number_to_bool(0.0), false);
assert_eq!(NumberExtension::number_to_bool(0.5), true);
assert_eq!(NumberExtension::number_to_bool(-1.0), true);
}
#[test]
fn test_number_extension_clamp() {
assert_eq!(NumberExtension::clamp(5.0, 0.0, 10.0), 5.0);
assert_eq!(NumberExtension::clamp(-1.0, 0.0, 10.0), 0.0);
assert_eq!(NumberExtension::clamp(15.0, 0.0, 10.0), 10.0);
}
#[test]
fn test_number_extension_range() {
assert!(NumberExtension::is_in_range(5.0, 0.0, 10.0));
assert!(!NumberExtension::is_in_range(-1.0, 0.0, 10.0));
assert!(!NumberExtension::is_in_range(15.0, 0.0, 10.0));
}
#[test]
fn test_number_extension_round() {
assert_eq!(NumberExtension::round_to_decimal_places(3.14159, 2), 3.14);
assert_eq!(NumberExtension::round_to_decimal_places(3.14159, 0), 3.0);
}
#[test]
fn test_number_extension_angle_conversion() {
let degrees = NumberExtension::radians_to_degrees(std::f64::consts::PI);
assert!((degrees - 180.0).abs() < 0.001);
let radians = NumberExtension::degrees_to_radians(180.0);
assert!((radians - std::f64::consts::PI).abs() < 0.001);
}
#[test]
fn test_number_extension_lerp() {
assert_eq!(NumberExtension::lerp(0.0, 10.0, 0.5), 5.0);
assert_eq!(NumberExtension::lerp(0.0, 10.0, 0.0), 0.0);
assert_eq!(NumberExtension::lerp(0.0, 10.0, 1.0), 10.0);
assert_eq!(NumberExtension::inverse_lerp(0.0, 10.0, 5.0), 0.5);
}
#[test]
fn test_number_extension_distance() {
assert_eq!(NumberExtension::distance(5.0, 3.0), 2.0);
assert_eq!(NumberExtension::distance(3.0, 5.0), 2.0);
assert_eq!(NumberExtension::distance(-2.0, 3.0), 5.0);
}
#[test]
fn test_number_extension_approximately_equal() {
assert!(NumberExtension::approximately_equal(1.0, 1.0000001, Some(0.001)));
assert!(!NumberExtension::approximately_equal(1.0, 1.1, Some(0.001)));
}
#[test]
fn test_number_extension_wrap() {
assert_eq!(NumberExtension::wrap(5.0, 10.0), 5.0);
assert_eq!(NumberExtension::wrap(15.0, 10.0), 5.0);
assert_eq!(NumberExtension::wrap(-1.0, 10.0), 9.0);
}
#[test]
fn test_number_extension_sign() {
assert_eq!(NumberExtension::sign(5.0), 1.0);
assert_eq!(NumberExtension::sign(-5.0), -1.0);
assert_eq!(NumberExtension::sign(0.0), 0.0);
}
#[test]
fn test_type_utils_type_id() {
assert_eq!(TypeUtils::get_type_id::<i32>(), TypeUtils::get_type_id::<i32>());
assert_ne!(TypeUtils::get_type_id::<i32>(), TypeUtils::get_type_id::<f64>());
let value = 42i32;
assert_eq!(TypeUtils::get_object_type_id(&value), TypeUtils::get_type_id::<i32>());
}
#[test]
fn test_type_utils_type_name() {
assert!(TypeUtils::get_type_name::<i32>().contains("i32"));
let value = 42i32;
assert!(TypeUtils::get_object_type_name(&value).contains("i32"));
}
#[test]
fn test_type_utils_same_type() {
assert!(TypeUtils::is_same_type::<i32, i32>());
assert!(!TypeUtils::is_same_type::<i32, f64>());
}
#[test]
fn test_type_utils_size() {
assert_eq!(TypeUtils::get_type_size::<i32>(), 4);
assert_eq!(TypeUtils::get_type_size::<i64>(), 8);
let value = 42i32;
assert_eq!(TypeUtils::get_object_size(&value), 4);
}
#[test]
fn test_type_utils_zero_sized() {
assert!(TypeUtils::is_zero_sized::<()>());
assert!(!TypeUtils::is_zero_sized::<i32>());
}
#[test]
fn test_string_extension_null_checks() {
assert!(StringExtension::is_null_or_empty(None));
assert!(StringExtension::is_null_or_empty(Some("")));
assert!(!StringExtension::is_null_or_empty(Some("hello")));
assert!(StringExtension::is_null_or_whitespace(None));
assert!(StringExtension::is_null_or_whitespace(Some(" ")));
assert!(!StringExtension::is_null_or_whitespace(Some("hello")));
}
#[test]
fn test_string_extension_truncate() {
assert_eq!(StringExtension::truncate("hello world", 5), "hello...");
assert_eq!(StringExtension::truncate("hi", 10), "hi");
}
#[test]
fn test_string_extension_case_conversion() {
assert_eq!(StringExtension::to_pascal_case("hello world"), "HelloWorld");
assert_eq!(StringExtension::to_camel_case("hello world"), "helloWorld");
assert_eq!(StringExtension::to_snake_case("HelloWorld"), "hello_world");
}
#[test]
fn test_string_extension_padding() {
assert_eq!(StringExtension::pad_left("123", 5, '0'), "00123");
assert_eq!(StringExtension::pad_right("123", 5, '0'), "12300");
}
#[test]
fn test_string_extension_reverse() {
assert_eq!(StringExtension::reverse("hello"), "olleh");
}
#[test]
fn test_string_extension_count_occurrences() {
assert_eq!(StringExtension::count_occurrences("hello world hello", "hello"), 2);
assert_eq!(StringExtension::count_occurrences("test", "xyz"), 0);
}
#[test]
fn test_collection_extension_null_checks() {
assert!(CollectionExtension::is_null_or_empty(None::<&Vec<i32>>));
assert!(CollectionExtension::is_null_or_empty(Some(&Vec::<i32>::new())));
assert!(!CollectionExtension::is_null_or_empty(Some(&vec![1, 2, 3])));
}
#[test]
fn test_collection_extension_safe_get() {
let vec = vec![1, 2, 3];
assert_eq!(CollectionExtension::get_safe(&vec, 0), Some(&1));
assert_eq!(CollectionExtension::get_safe(&vec, 5), None);
}
#[test]
fn test_collection_extension_find() {
let vec = vec![1, 2, 3, 4, 5];
assert_eq!(CollectionExtension::find(&vec, |&x| x > 3), Some(&4));
assert_eq!(CollectionExtension::find(&vec, |&x| x > 10), None);
let found_all = CollectionExtension::find_all(&vec, |&x| x > 3);
assert_eq!(found_all, vec![&4, &5]);
}
#[test]
fn test_collection_extension_predicates() {
let vec = vec![1, 2, 3, 4, 5];
assert!(CollectionExtension::exists(&vec, |&x| x > 3));
assert!(!CollectionExtension::exists(&vec, |&x| x > 10));
assert!(CollectionExtension::all(&vec, |&x| x > 0));
assert!(!CollectionExtension::all(&vec, |&x| x > 3));
}
#[test]
fn test_collection_extension_math() {
let vec = vec![1.0, 2.0, 3.0, 4.0, 5.0];
assert_eq!(CollectionExtension::sum(&vec), 15.0);
assert_eq!(CollectionExtension::average(&vec), Some(3.0));
let int_vec = vec![1, 5, 3, 2, 4];
assert_eq!(CollectionExtension::max(&int_vec), Some(5));
assert_eq!(CollectionExtension::min(&int_vec), Some(1));
}
#[test]
fn test_collection_extension_distinct() {
let vec = vec![1, 2, 2, 3, 1, 4];
let distinct = CollectionExtension::distinct(&vec);
assert_eq!(distinct, vec![1, 2, 3, 4]);
}
#[test]
fn test_collection_extension_chunk() {
let vec = vec![1, 2, 3, 4, 5, 6, 7];
let chunks = CollectionExtension::chunk(&vec, 3);
assert_eq!(chunks.len(), 3);
assert_eq!(chunks[0], &[1, 2, 3]);
assert_eq!(chunks[1], &[4, 5, 6]);
assert_eq!(chunks[2], &[7]);
}
#[test]
fn test_number_extension_to_number_from_option() {
assert_eq!(NumberExtension::to_number_from_option(Some(42)), 42.0);
let result = NumberExtension::to_number_from_option(Some(3.14f32));
assert!((result - 3.14).abs() < 0.0001); // 使用近似相等检查浮点数
assert_eq!(NumberExtension::to_number_from_option::<i32>(None), 0.0);
}
}

View File

@@ -0,0 +1,518 @@
use std::collections::HashMap;
/**
* 延迟回收项结构
*/
#[derive(Debug, Clone)]
struct PendingRecycleItem {
index: u16,
generation: u16,
timestamp: u64,
}
/**
* 世代式ID池统计信息
*/
#[derive(Debug, Clone, Default)]
pub struct IdentifierPoolStats {
/// 已分配的总索引数
pub total_allocated: u64,
/// 总计回收次数
pub total_recycled: u64,
/// 当前活跃实体数
pub current_active: u32,
/// 当前空闲的索引数
pub currently_free: u32,
/// 等待回收的ID数
pub pending_recycle: u32,
/// 理论最大实体数(设计限制)
pub max_possible_entities: u32,
/// 当前使用的最大索引
pub max_used_index: u16,
/// 内存使用(字节)
pub memory_usage: usize,
/// 内存扩展次数
pub memory_expansions: u32,
/// 平均世代版本
pub average_generation: f64,
/// 世代存储大小
pub generation_storage_size: usize,
}
/**
* 世代式ID池管理器
*
* 用于管理实体ID的分配和回收支持世代版本控制以防止悬空引用问题。
* 世代式ID由索引和版本组成当ID被回收时版本会递增确保旧引用失效。
*
* 支持动态扩展理论上可以支持到65535个索引16位每个索引65535个版本16位
* 总计可以处理超过42亿个独特的ID组合完全满足ECS大规模实体需求。
*/
#[derive(Debug)]
pub struct IdentifierPool {
/// 下一个可用的索引
next_available_index: u16,
/// 空闲的索引列表
free_indices: Vec<u16>,
/// 每个索引对应的世代版本
/// 使用HashMap实现动态扩展
generations: HashMap<u16, u16>,
/// 延迟回收队列
/// 防止在同一帧内立即重用ID避免时序问题
pending_recycle: Vec<PendingRecycleItem>,
/// 延迟回收时间(毫秒)
recycle_delay: u64,
/// 内存扩展块大小
expansion_block_size: u16,
/// 统计信息
stats: IdentifierPoolStats,
}
impl IdentifierPool {
/// 最大索引限制16位
/// 这是框架设计选择16位索引 + 16位版本 = 32位ID确保高效位操作
pub const MAX_INDEX: u16 = 0xFFFF; // 65535
/// 最大世代限制16位
pub const MAX_GENERATION: u16 = 0xFFFF; // 65535
/**
* 构造函数
*
* @param recycle_delay 延迟回收时间毫秒默认为100ms
* @param expansion_block_size 内存扩展块大小默认为1024
*/
pub fn new(recycle_delay: u64, expansion_block_size: u16) -> Self {
let mut pool = Self {
next_available_index: 0,
free_indices: Vec::new(),
generations: HashMap::new(),
pending_recycle: Vec::new(),
recycle_delay,
expansion_block_size,
stats: IdentifierPoolStats::default(),
};
// 预分配第一个块的世代信息
pool.pre_allocate_generations(0, pool.expansion_block_size);
pool
}
/**
* 使用默认参数创建ID池
*/
pub fn with_defaults() -> Self {
Self::new(100, 1024)
}
/**
* 获取一个可用的ID
*
* 返回一个32位ID高16位为世代版本低16位为索引。
*
* @returns 新分配的实体ID
* @throws Error 当达到索引限制时
*/
pub fn check_out(&mut self) -> Result<u32, String> {
// 处理延迟回收队列
self.process_delayed_recycle(false);
let index: u16;
if let Some(recycled_index) = self.free_indices.pop() {
// 重用回收的索引
index = recycled_index;
} else {
// 分配新索引
if self.next_available_index >= Self::MAX_INDEX {
return Err(format!(
"实体索引已达到框架设计限制 ({})。\
这意味着您已经分配了超过65535个不同的实体索引。\
这是16位索引设计的限制考虑优化实体回收策略或升级到64位ID设计。",
Self::MAX_INDEX
));
}
index = self.next_available_index;
self.next_available_index += 1;
// 按需扩展世代存储
self.ensure_generation_capacity(index);
}
let generation = self.generations.get(&index).copied().unwrap_or(1);
self.stats.total_allocated += 1;
self.stats.current_active += 1;
Ok(self.pack_id(index, generation))
}
/**
* 回收一个ID
*
* 验证ID的有效性后将其加入延迟回收队列。
* ID不会立即可重用而是在延迟时间后才真正回收。
*
* @param id 要回收的实体ID
* @returns 是否成功回收ID是否有效且未被重复回收
*/
pub fn check_in(&mut self, id: u32) -> bool {
let index = self.unpack_index(id);
let generation = self.unpack_generation(id);
// 验证ID有效性
if !self.is_valid_id(index, generation) {
return false;
}
// 检查是否已经在待回收队列中
let already_pending = self.pending_recycle.iter()
.any(|item| item.index == index && item.generation == generation);
if already_pending {
return false; // 已经在回收队列中,拒绝重复回收
}
// 加入延迟回收队列
self.pending_recycle.push(PendingRecycleItem {
index,
generation,
timestamp: self.get_current_time_ms(),
});
self.stats.current_active -= 1;
self.stats.total_recycled += 1;
true
}
/**
* 验证ID是否有效
*
* 检查ID的索引和世代版本是否匹配当前状态。
*
* @param id 要验证的实体ID
* @returns ID是否有效
*/
pub fn is_valid(&self, id: u32) -> bool {
let index = self.unpack_index(id);
let generation = self.unpack_generation(id);
self.is_valid_id(index, generation)
}
/**
* 获取统计信息
*
* @returns 池的当前状态统计
*/
pub fn get_stats(&self) -> IdentifierPoolStats {
// 计算平均世代版本
let (total_generation, generation_count) = self.generations.iter()
.filter(|(&index, _)| index < self.next_available_index)
.fold((0u64, 0u32), |(sum, count), (_, &generation)| {
(sum + generation as u64, count + 1)
});
let average_generation = if generation_count > 0 {
(total_generation as f64) / (generation_count as f64)
} else {
1.0
};
IdentifierPoolStats {
total_allocated: self.stats.total_allocated,
total_recycled: self.stats.total_recycled,
current_active: self.stats.current_active,
currently_free: self.free_indices.len() as u32,
pending_recycle: self.pending_recycle.len() as u32,
max_possible_entities: (Self::MAX_INDEX as u32) + 1,
max_used_index: if self.next_available_index > 0 {
self.next_available_index - 1
} else {
0
},
memory_usage: self.calculate_memory_usage(),
memory_expansions: self.stats.memory_expansions,
average_generation: (average_generation * 100.0).round() / 100.0,
generation_storage_size: self.generations.len(),
}
}
/**
* 强制执行延迟回收处理
*
* 在某些情况下可能需要立即处理延迟回收队列,
* 比如内存压力大或者需要精确的统计信息时。
*/
pub fn force_process_delayed_recycle(&mut self) {
self.process_delayed_recycle(true);
}
/**
* 清理过期的延迟回收项
*
* 将超过延迟时间的回收项真正回收到空闲列表中。
*
* @param force_all 是否强制处理所有延迟回收项
*/
fn process_delayed_recycle(&mut self, force_all: bool) {
if self.pending_recycle.is_empty() {
return;
}
let now = self.get_current_time_ms();
let mut ready_to_recycle = Vec::new();
let mut still_pending = Vec::new();
// 分离已到期和未到期的项
for item in self.pending_recycle.drain(..) {
if force_all || now.saturating_sub(item.timestamp) >= self.recycle_delay {
ready_to_recycle.push(item);
} else {
still_pending.push(item);
}
}
// 处理到期的回收项
for item in ready_to_recycle {
// 再次验证ID有效性防止重复回收
if self.is_valid_id(item.index, item.generation) {
// 递增世代版本
let new_generation = if item.generation >= Self::MAX_GENERATION {
1 // 重置为1而不是0
} else {
item.generation + 1
};
self.generations.insert(item.index, new_generation);
// 添加到空闲列表
self.free_indices.push(item.index);
}
}
// 更新待回收队列
self.pending_recycle = still_pending;
}
/**
* 预分配世代信息
*
* @param start_index 起始索引
* @param count 分配数量
*/
fn pre_allocate_generations(&mut self, start_index: u16, count: u16) {
for i in 0..count {
let index = start_index.saturating_add(i);
if index <= Self::MAX_INDEX {
self.generations.insert(index, 1);
} else {
break;
}
}
self.stats.memory_expansions += 1;
}
/**
* 确保指定索引的世代信息存在
*
* @param index 索引
*/
fn ensure_generation_capacity(&mut self, index: u16) {
if !self.generations.contains_key(&index) {
// 计算需要扩展的起始位置
let expansion_start = (index / self.expansion_block_size) * self.expansion_block_size;
// 预分配一个块
self.pre_allocate_generations(expansion_start, self.expansion_block_size);
}
}
/**
* 计算内存使用量
*
* @returns 内存使用字节数
*/
fn calculate_memory_usage(&self) -> usize {
let generation_map_size = self.generations.len() * (std::mem::size_of::<u16>() * 2 + 24); // HashMap overhead
let free_indices_size = self.free_indices.capacity() * std::mem::size_of::<u16>();
let pending_recycle_size = self.pending_recycle.capacity() * std::mem::size_of::<PendingRecycleItem>();
generation_map_size + free_indices_size + pending_recycle_size
}
/**
* 打包索引和世代为32位ID
*
* @param index 索引16位
* @param generation 世代版本16位
* @returns 打包后的32位ID
*/
fn pack_id(&self, index: u16, generation: u16) -> u32 {
((generation as u32) << 16) | (index as u32)
}
/**
* 从ID中解包索引
*
* @param id 32位ID
* @returns 索引部分16位
*/
fn unpack_index(&self, id: u32) -> u16 {
(id & 0xFFFF) as u16
}
/**
* 从ID中解包世代版本
*
* @param id 32位ID
* @returns 世代版本部分16位
*/
fn unpack_generation(&self, id: u32) -> u16 {
((id >> 16) & 0xFFFF) as u16
}
/**
* 内部ID有效性检查
*
* @param index 索引
* @param generation 世代版本
* @returns 是否有效
*/
fn is_valid_id(&self, index: u16, generation: u16) -> bool {
if index >= self.next_available_index {
return false;
}
if let Some(&current_generation) = self.generations.get(&index) {
current_generation == generation
} else {
false
}
}
/**
* 获取当前时间(毫秒)
* 在实际应用中应该使用更准确的时间源
*/
fn get_current_time_ms(&self) -> u64 {
// 简单的时间实现,实际使用中可能需要更精确的时间源
// 在WASM环境中可以通过js_sys::Date获取
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
}
impl Default for IdentifierPool {
fn default() -> Self {
Self::with_defaults()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_identifier_pool_basic() {
let mut pool = IdentifierPool::with_defaults();
// 分配ID
let id1 = pool.check_out().unwrap();
let id2 = pool.check_out().unwrap();
assert_ne!(id1, id2);
assert!(pool.is_valid(id1));
assert!(pool.is_valid(id2));
let stats = pool.get_stats();
assert_eq!(stats.current_active, 2);
assert_eq!(stats.total_allocated, 2);
}
#[test]
fn test_identifier_pool_recycle() {
let mut pool = IdentifierPool::with_defaults();
let id = pool.check_out().unwrap();
assert!(pool.is_valid(id));
// 回收ID
assert!(pool.check_in(id));
// ID应该仍然有效直到延迟回收处理
assert!(pool.is_valid(id));
// 强制处理延迟回收
pool.force_process_delayed_recycle();
// 现在ID应该无效
assert!(!pool.is_valid(id));
let stats = pool.get_stats();
assert_eq!(stats.current_active, 0);
assert_eq!(stats.currently_free, 1);
}
#[test]
fn test_identifier_pool_generation_increment() {
let mut pool = IdentifierPool::with_defaults();
let id1 = pool.check_out().unwrap();
let index = pool.unpack_index(id1);
let generation1 = pool.unpack_generation(id1);
// 回收并强制处理
pool.check_in(id1);
pool.force_process_delayed_recycle();
// 重新分配同一个索引
let id2 = pool.check_out().unwrap();
let index2 = pool.unpack_index(id2);
let generation2 = pool.unpack_generation(id2);
assert_eq!(index, index2); // 同一个索引
assert_eq!(generation2, generation1 + 1); // 世代递增
assert!(!pool.is_valid(id1)); // 旧ID无效
assert!(pool.is_valid(id2)); // 新ID有效
}
#[test]
fn test_identifier_pool_double_recycle() {
let mut pool = IdentifierPool::with_defaults();
let id = pool.check_out().unwrap();
// 第一次回收应该成功
assert!(pool.check_in(id));
// 第二次回收应该失败
assert!(!pool.check_in(id));
}
#[test]
fn test_identifier_pool_stats() {
let mut pool = IdentifierPool::with_defaults();
let _id1 = pool.check_out().unwrap();
let id2 = pool.check_out().unwrap();
let _id3 = pool.check_out().unwrap();
pool.check_in(id2);
let stats = pool.get_stats();
assert_eq!(stats.total_allocated, 3);
assert_eq!(stats.total_recycled, 1);
assert_eq!(stats.current_active, 2);
assert_eq!(stats.pending_recycle, 1);
assert_eq!(stats.max_used_index, 2);
}
}

View File

@@ -0,0 +1,456 @@
use std::any::TypeId;
/**
* 组件类型标识符
* 在Rust中使用TypeId来标识组件类型
*/
pub type ComponentType = TypeId;
/**
* 查询条件结构
* 定义实体查询的所有条件类型
*/
#[derive(Debug, Clone)]
pub struct QueryCondition {
/// 必须包含所有这些组件
pub all: Vec<ComponentType>,
/// 必须包含至少一个这些组件
pub any: Vec<ComponentType>,
/// 不能包含任何这些组件
pub none: Vec<ComponentType>,
/// 按标签查询
pub tag: Option<u32>,
/// 按名称查询
pub name: Option<String>,
/// 单组件查询
pub component: Option<ComponentType>,
}
impl Default for QueryCondition {
fn default() -> Self {
Self {
all: Vec::new(),
any: Vec::new(),
none: Vec::new(),
tag: None,
name: None,
component: None,
}
}
}
/**
* 实体匹配条件描述符
*
* 用于描述实体查询条件,不执行实际查询
* 支持链式调用构建复杂查询条件
*/
#[derive(Debug)]
pub struct Matcher {
condition: QueryCondition,
}
impl Matcher {
/**
* 创建新的匹配器
*/
pub fn new() -> Self {
Self {
condition: QueryCondition::default(),
}
}
// ========== 静态构造方法 ==========
/**
* 创建匹配器,要求所有指定的组件
*/
pub fn all_of(component_types: &[ComponentType]) -> Self {
let mut matcher = Self::new();
matcher.all_of_types(component_types);
matcher
}
/**
* 创建匹配器,要求至少一个指定的组件
*/
pub fn any_of(component_types: &[ComponentType]) -> Self {
let mut matcher = Self::new();
matcher.any_of_types(component_types);
matcher
}
/**
* 创建匹配器,排除指定的组件
*/
pub fn none_of(component_types: &[ComponentType]) -> Self {
let mut matcher = Self::new();
matcher.none_of_types(component_types);
matcher
}
/**
* 创建按标签查询的匹配器
*/
pub fn by_tag(tag: u32) -> Self {
let mut matcher = Self::new();
matcher.with_tag(tag);
matcher
}
/**
* 创建按名称查询的匹配器
*/
pub fn by_name(name: String) -> Self {
let mut matcher = Self::new();
matcher.with_name(name);
matcher
}
/**
* 创建单组件查询的匹配器
*/
pub fn by_component(component_type: ComponentType) -> Self {
let mut matcher = Self::new();
matcher.with_component(component_type);
matcher
}
/**
* 创建复杂查询构建器
*/
pub fn complex() -> Self {
Self::new()
}
/**
* 创建空匹配器(向后兼容)
*/
pub fn empty() -> Self {
Self::new()
}
// ========== 链式构建方法 ==========
/**
* 必须包含所有指定组件
*/
pub fn all_of_types(&mut self, component_types: &[ComponentType]) -> &mut Self {
self.condition.all.extend_from_slice(component_types);
self
}
/**
* 必须包含所有指定组件(单个组件版本)
*/
pub fn all(&mut self, component_type: ComponentType) -> &mut Self {
self.condition.all.push(component_type);
self
}
/**
* 必须包含至少一个指定组件
*/
pub fn any_of_types(&mut self, component_types: &[ComponentType]) -> &mut Self {
self.condition.any.extend_from_slice(component_types);
self
}
/**
* 必须包含至少一个指定组件(单个组件版本)
*/
pub fn any(&mut self, component_type: ComponentType) -> &mut Self {
self.condition.any.push(component_type);
self
}
/**
* 不能包含任何指定组件
*/
pub fn none_of_types(&mut self, component_types: &[ComponentType]) -> &mut Self {
self.condition.none.extend_from_slice(component_types);
self
}
/**
* 不能包含指定组件(单个组件版本)
*/
pub fn none(&mut self, component_type: ComponentType) -> &mut Self {
self.condition.none.push(component_type);
self
}
/**
* 排除指定组件(别名方法)
*/
pub fn exclude(&mut self, component_type: ComponentType) -> &mut Self {
self.none(component_type)
}
/**
* 至少包含其中之一(别名方法)
*/
pub fn one(&mut self, component_type: ComponentType) -> &mut Self {
self.any(component_type)
}
/**
* 按标签查询
*/
pub fn with_tag(&mut self, tag: u32) -> &mut Self {
self.condition.tag = Some(tag);
self
}
/**
* 按名称查询
*/
pub fn with_name(&mut self, name: String) -> &mut Self {
self.condition.name = Some(name);
self
}
/**
* 单组件查询
*/
pub fn with_component(&mut self, component_type: ComponentType) -> &mut Self {
self.condition.component = Some(component_type);
self
}
/**
* 移除标签条件
*/
pub fn without_tag(&mut self) -> &mut Self {
self.condition.tag = None;
self
}
/**
* 移除名称条件
*/
pub fn without_name(&mut self) -> &mut Self {
self.condition.name = None;
self
}
/**
* 移除单组件条件
*/
pub fn without_component(&mut self) -> &mut Self {
self.condition.component = None;
self
}
// ========== 查询和工具方法 ==========
/**
* 获取查询条件(只读)
*/
pub fn get_condition(&self) -> &QueryCondition {
&self.condition
}
/**
* 获取查询条件的克隆
*/
pub fn clone_condition(&self) -> QueryCondition {
self.condition.clone()
}
/**
* 检查是否为空条件
*/
pub fn is_empty(&self) -> bool {
self.condition.all.is_empty() &&
self.condition.any.is_empty() &&
self.condition.none.is_empty() &&
self.condition.tag.is_none() &&
self.condition.name.is_none() &&
self.condition.component.is_none()
}
/**
* 重置所有条件
*/
pub fn reset(&mut self) -> &mut Self {
self.condition.all.clear();
self.condition.any.clear();
self.condition.none.clear();
self.condition.tag = None;
self.condition.name = None;
self.condition.component = None;
self
}
/**
* 克隆匹配器
*/
pub fn clone(&self) -> Self {
Self {
condition: self.condition.clone(),
}
}
/**
* 获取所有条件的组件类型数量(用于性能分析)
*/
pub fn component_type_count(&self) -> usize {
self.condition.all.len() +
self.condition.any.len() +
self.condition.none.len() +
if self.condition.component.is_some() { 1 } else { 0 }
}
/**
* 检查查询条件的复杂度
*/
pub fn complexity_level(&self) -> u32 {
let mut level = 0;
if !self.condition.all.is_empty() { level += 1; }
if !self.condition.any.is_empty() { level += 2; }
if !self.condition.none.is_empty() { level += 1; }
if self.condition.tag.is_some() { level += 1; }
if self.condition.name.is_some() { level += 1; }
if self.condition.component.is_some() { level += 1; }
level
}
}
impl Default for Matcher {
fn default() -> Self {
Self::new()
}
}
/**
* 用于测试和调试的方法
*/
impl Matcher {
/**
* 格式化为调试字符串
*/
pub fn debug_string(&self) -> String {
let mut parts = Vec::new();
if !self.condition.all.is_empty() {
parts.push(format!("all({} types)", self.condition.all.len()));
}
if !self.condition.any.is_empty() {
parts.push(format!("any({} types)", self.condition.any.len()));
}
if !self.condition.none.is_empty() {
parts.push(format!("none({} types)", self.condition.none.len()));
}
if let Some(tag) = self.condition.tag {
parts.push(format!("tag({})", tag));
}
if let Some(ref name) = self.condition.name {
parts.push(format!("name({})", name));
}
if self.condition.component.is_some() {
parts.push("component(1 type)".to_string());
}
if parts.is_empty() {
"Matcher[empty]".to_string()
} else {
format!("Matcher[{}]", parts.join(" & "))
}
}
}
// 实现Display trait以支持打印
impl std::fmt::Display for Matcher {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.debug_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::any::TypeId;
// 测试用的示例组件
struct TestComponent1;
struct TestComponent2;
struct TestComponent3;
#[test]
fn test_matcher_all() {
let mut matcher = Matcher::new();
matcher.all(TypeId::of::<TestComponent1>())
.all(TypeId::of::<TestComponent2>());
assert_eq!(matcher.get_condition().all.len(), 2);
assert!(!matcher.is_empty());
}
#[test]
fn test_matcher_any() {
let mut matcher = Matcher::new();
matcher.any(TypeId::of::<TestComponent1>())
.any(TypeId::of::<TestComponent2>());
assert_eq!(matcher.get_condition().any.len(), 2);
}
#[test]
fn test_matcher_none() {
let mut matcher = Matcher::new();
matcher.none(TypeId::of::<TestComponent1>());
assert_eq!(matcher.get_condition().none.len(), 1);
}
#[test]
fn test_matcher_complex() {
let mut matcher = Matcher::complex();
matcher.all(TypeId::of::<TestComponent1>())
.any(TypeId::of::<TestComponent2>())
.none(TypeId::of::<TestComponent3>())
.with_tag(42)
.with_name("test_entity".to_string());
assert_eq!(matcher.complexity_level(), 6);
assert!(!matcher.is_empty());
}
#[test]
fn test_matcher_static_constructors() {
let types = vec![TypeId::of::<TestComponent1>(), TypeId::of::<TestComponent2>()];
let matcher = Matcher::all_of(&types);
assert_eq!(matcher.get_condition().all.len(), 2);
}
#[test]
fn test_matcher_reset() {
let mut matcher = Matcher::new();
matcher.all(TypeId::of::<TestComponent1>())
.with_tag(42);
assert!(!matcher.is_empty());
matcher.reset();
assert!(matcher.is_empty());
}
#[test]
fn test_matcher_clone() {
let mut matcher = Matcher::new();
matcher.all(TypeId::of::<TestComponent1>())
.with_tag(42);
let cloned = matcher.clone();
assert_eq!(cloned.get_condition().all.len(), 1);
assert_eq!(cloned.get_condition().tag, Some(42));
}
}

View File

@@ -0,0 +1,46 @@
pub mod sparse_set;
pub mod time;
pub mod matcher;
pub mod identifier_pool;
pub mod component_pool;
pub mod dirty_tracking;
pub mod performance_monitor;
pub mod timer;
pub mod pool;
pub mod debug;
pub mod updatable;
pub mod extensions;
pub use sparse_set::SparseSet;
pub use time::Time;
pub use matcher::{Matcher, QueryCondition, ComponentType};
pub use identifier_pool::{IdentifierPool, IdentifierPoolStats};
pub use component_pool::{ComponentPool, ComponentPoolManager, ComponentPoolStats, ComponentPoolManagerStats, PoolStatsSummary};
pub use dirty_tracking::{DirtyTrackingSystem, DirtyFlag, DirtyData, DirtyTrackingStats, DirtyListener, DirtyListenerConfig};
pub use performance_monitor::{PerformanceMonitor, PerformanceData, PerformanceStats, PerformanceWarning, PerformanceWarningType, WarningSeverity, PerformanceThresholds, ThresholdPair};
pub use timer::{Timer, TimerManager, ITimer, TimerContext, TimerCallback, EmptyContext};
pub use pool::{Pool, PoolManager, Poolable, PoolStats};
pub use debug::{DebugManager, EntityDataCollector, SystemDataCollector, ComponentDataCollector, PerformanceDataCollector, DebugEntityData, DebugComponentInfo, DebugSystemInfo, DebugArchetypeInfo, DebugPerformanceInfo, DebugWarning, WarningLevel, DebugStats, DebugData};
pub use updatable::{IUpdatable, IUpdatableComparer, SceneComponent, SceneComponentTrait, UpdatableManager, SceneComponentManager, is_updatable};
pub use extensions::{NumberExtension, TypeUtils, StringExtension, CollectionExtension};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn error(msg: String);
}
#[cfg(feature = "console_error_panic_hook")]
pub fn set_panic_hook() {
console_error_panic_hook::set_once();
}
#[cfg(not(feature = "console_error_panic_hook"))]
pub fn set_panic_hook() {}
#[allow(dead_code)]
pub fn log_error(msg: &str) {
error(msg.to_string());
}

View File

@@ -0,0 +1,824 @@
use rustc_hash::FxHashMap;
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use std::collections::VecDeque;
/**
* 性能数据
*/
#[derive(Debug, Clone)]
pub struct PerformanceData {
/// 系统名称
pub name: String,
/// 执行时间(毫秒)
pub execution_time: f64,
/// 处理的实体数量
pub entity_count: usize,
/// 平均每个实体的处理时间
pub average_time_per_entity: f64,
/// 最后更新时间戳
pub last_update_time: u64,
/// 内存使用量(字节)
pub memory_usage: Option<usize>,
/// CPU使用率百分比
pub cpu_usage: Option<f64>,
}
/**
* 性能统计信息
*/
#[derive(Debug, Clone)]
pub struct PerformanceStats {
/// 总执行时间
pub total_time: f64,
/// 平均执行时间
pub average_time: f64,
/// 最小执行时间
pub min_time: f64,
/// 最大执行时间
pub max_time: f64,
/// 执行次数
pub execution_count: u64,
/// 最近的执行时间列表
pub recent_times: VecDeque<f64>,
/// 标准差
pub standard_deviation: f64,
/// 95百分位数
pub percentile_95: f64,
/// 99百分位数
pub percentile_99: f64,
}
impl Default for PerformanceStats {
fn default() -> Self {
Self {
total_time: 0.0,
average_time: 0.0,
min_time: f64::MAX,
max_time: 0.0,
execution_count: 0,
recent_times: VecDeque::new(),
standard_deviation: 0.0,
percentile_95: 0.0,
percentile_99: 0.0,
}
}
}
/**
* 性能警告类型
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PerformanceWarningType {
HighExecutionTime,
HighMemoryUsage,
HighCpuUsage,
FrequentGc,
LowFps,
HighEntityCount,
}
/**
* 性能警告
*/
#[derive(Debug, Clone)]
pub struct PerformanceWarning {
pub warning_type: PerformanceWarningType,
pub system_name: String,
pub message: String,
pub severity: WarningSeverity,
pub timestamp: u64,
pub value: f64,
pub threshold: f64,
pub suggestion: Option<String>,
}
/**
* 警告严重程度
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WarningSeverity {
Low,
Medium,
High,
Critical,
}
/**
* 性能阈值配置
*/
#[derive(Debug, Clone)]
pub struct PerformanceThresholds {
/// 执行时间阈值(毫秒)
pub execution_time: ThresholdPair,
/// 内存使用阈值MB
pub memory_usage: ThresholdPair,
/// CPU使用率阈值百分比
pub cpu_usage: ThresholdPair,
/// FPS阈值
pub fps: ThresholdPair,
/// 实体数量阈值
pub entity_count: ThresholdPair,
}
/**
* 阈值对(警告和临界值)
*/
#[derive(Debug, Clone)]
pub struct ThresholdPair {
pub warning: f64,
pub critical: f64,
}
impl Default for PerformanceThresholds {
fn default() -> Self {
Self {
execution_time: ThresholdPair { warning: 16.67, critical: 33.33 }, // 60fps和30fps对应的帧时间
memory_usage: ThresholdPair { warning: 100.0, critical: 200.0 }, // MB
cpu_usage: ThresholdPair { warning: 70.0, critical: 90.0 }, // 百分比
fps: ThresholdPair { warning: 45.0, critical: 30.0 },
entity_count: ThresholdPair { warning: 1000.0, critical: 5000.0 },
}
}
}
/**
* 高性能监控器
* 用于监控ECS系统的性能表现提供详细的分析和优化建议
*/
pub struct PerformanceMonitor {
system_data: FxHashMap<String, PerformanceData>,
system_stats: FxHashMap<String, PerformanceStats>,
warnings: Vec<PerformanceWarning>,
is_enabled: bool,
max_recent_samples: usize,
max_warnings: usize,
// 性能阈值配置
thresholds: PerformanceThresholds,
// FPS监控
fps_history: VecDeque<f64>,
last_frame_time: Option<Instant>,
frame_count: u64,
fps_update_interval: u64, // 毫秒
last_fps_update: u64,
current_fps: f64,
// 内存监控
memory_check_interval: u64, // 毫秒
last_memory_check: u64,
memory_history: Vec<usize>,
// GC监控
gc_count: u64,
last_gc_check: u64,
gc_check_interval: u64,
}
impl Default for PerformanceMonitor {
fn default() -> Self {
Self::new()
}
}
impl PerformanceMonitor {
/**
* 创建新的性能监控器
*/
pub fn new() -> Self {
Self {
system_data: FxHashMap::default(),
system_stats: FxHashMap::default(),
warnings: Vec::new(),
is_enabled: false,
max_recent_samples: 60, // 保留最近60帧的数据
max_warnings: 100, // 最大警告数量
thresholds: PerformanceThresholds::default(),
fps_history: VecDeque::new(),
last_frame_time: None,
frame_count: 0,
fps_update_interval: 1000, // 1秒更新一次FPS
last_fps_update: 0,
current_fps: 60.0,
memory_check_interval: 5000, // 5秒检查一次内存
last_memory_check: 0,
memory_history: Vec::new(),
gc_count: 0,
last_gc_check: 0,
gc_check_interval: 1000,
}
}
/**
* 启用性能监控
*/
pub fn enable(&mut self) {
self.is_enabled = true;
}
/**
* 禁用性能监控
*/
pub fn disable(&mut self) {
self.is_enabled = false;
}
/**
* 检查是否启用了性能监控
*/
pub fn is_enabled(&self) -> bool {
self.is_enabled
}
/**
* 开始监控系统性能
* 返回开始时间戳用于endMonitoring
*/
pub fn start_monitoring(&self, _system_name: &str) -> Option<Instant> {
if !self.is_enabled {
return None;
}
Some(Instant::now())
}
/**
* 结束监控并记录性能数据
*/
pub fn end_monitoring(
&mut self,
system_name: &str,
start_time: Option<Instant>,
entity_count: usize
) {
if !self.is_enabled || start_time.is_none() {
return;
}
let end_time = Instant::now();
let execution_time = end_time.duration_since(start_time.unwrap()).as_secs_f64() * 1000.0;
let average_time_per_entity = if entity_count > 0 {
execution_time / entity_count as f64
} else {
0.0
};
// 更新当前性能数据
let data = PerformanceData {
name: system_name.to_string(),
execution_time,
entity_count,
average_time_per_entity,
last_update_time: current_timestamp(),
memory_usage: None,
cpu_usage: None,
};
self.system_data.insert(system_name.to_string(), data);
// 更新统计信息
self.update_stats(system_name, execution_time);
// 检查警告
self.check_warnings(system_name, execution_time, entity_count);
}
/**
* 更新系统统计信息
*/
fn update_stats(&mut self, system_name: &str, execution_time: f64) {
{
let stats = self.system_stats.entry(system_name.to_string()).or_insert_with(PerformanceStats::default);
// 更新基本统计
stats.total_time += execution_time;
stats.execution_count += 1;
stats.average_time = stats.total_time / stats.execution_count as f64;
stats.min_time = stats.min_time.min(execution_time);
stats.max_time = stats.max_time.max(execution_time);
// 更新最近时间列表
stats.recent_times.push_back(execution_time);
if stats.recent_times.len() > self.max_recent_samples {
stats.recent_times.pop_front();
}
}
// 计算高级统计信息
if let Some(stats) = self.system_stats.get_mut(system_name) {
Self::calculate_advanced_stats_static(stats);
}
}
/**
* 计算高级统计信息
*/
fn calculate_advanced_stats_static(stats: &mut PerformanceStats) {
if stats.recent_times.is_empty() {
return;
}
// 计算标准差
let mean: f64 = stats.recent_times.iter().sum::<f64>() / stats.recent_times.len() as f64;
let variance: f64 = stats.recent_times.iter()
.map(|&time| (time - mean).powi(2))
.sum::<f64>() / stats.recent_times.len() as f64;
stats.standard_deviation = variance.sqrt();
// 计算百分位数
let mut sorted_times: Vec<f64> = stats.recent_times.iter().cloned().collect();
sorted_times.sort_by(|a, b| a.partial_cmp(b).unwrap());
let len = sorted_times.len();
if len > 0 {
let index_95 = ((len as f64 * 0.95) as usize).min(len - 1);
let index_99 = ((len as f64 * 0.99) as usize).min(len - 1);
stats.percentile_95 = sorted_times[index_95];
stats.percentile_99 = sorted_times[index_99];
}
}
/**
* 检查性能警告
*/
fn check_warnings(&mut self, system_name: &str, execution_time: f64, entity_count: usize) {
// 检查执行时间
if execution_time > self.thresholds.execution_time.critical {
self.add_warning(PerformanceWarning {
warning_type: PerformanceWarningType::HighExecutionTime,
system_name: system_name.to_string(),
message: format!("System {} execution time is critically high: {:.2}ms", system_name, execution_time),
severity: WarningSeverity::Critical,
timestamp: current_timestamp(),
value: execution_time,
threshold: self.thresholds.execution_time.critical,
suggestion: Some("Consider optimizing system logic or reducing entity count".to_string()),
});
} else if execution_time > self.thresholds.execution_time.warning {
self.add_warning(PerformanceWarning {
warning_type: PerformanceWarningType::HighExecutionTime,
system_name: system_name.to_string(),
message: format!("System {} execution time is high: {:.2}ms", system_name, execution_time),
severity: WarningSeverity::Medium,
timestamp: current_timestamp(),
value: execution_time,
threshold: self.thresholds.execution_time.warning,
suggestion: Some("Monitor system performance and consider optimization".to_string()),
});
}
// 检查实体数量
let entity_count_f64 = entity_count as f64;
if entity_count_f64 > self.thresholds.entity_count.critical {
self.add_warning(PerformanceWarning {
warning_type: PerformanceWarningType::HighEntityCount,
system_name: system_name.to_string(),
message: format!("System {} processing critically high entity count: {}", system_name, entity_count),
severity: WarningSeverity::Critical,
timestamp: current_timestamp(),
value: entity_count_f64,
threshold: self.thresholds.entity_count.critical,
suggestion: Some("Consider entity pooling or batch processing".to_string()),
});
} else if entity_count_f64 > self.thresholds.entity_count.warning {
self.add_warning(PerformanceWarning {
warning_type: PerformanceWarningType::HighEntityCount,
system_name: system_name.to_string(),
message: format!("System {} processing high entity count: {}", system_name, entity_count),
severity: WarningSeverity::Medium,
timestamp: current_timestamp(),
value: entity_count_f64,
threshold: self.thresholds.entity_count.warning,
suggestion: Some("Monitor entity count and consider optimization if it continues growing".to_string()),
});
}
}
/**
* 添加警告
*/
fn add_warning(&mut self, warning: PerformanceWarning) {
self.warnings.push(warning);
// 限制警告数量
if self.warnings.len() > self.max_warnings {
self.warnings.remove(0);
}
}
/**
* 获取系统的当前性能数据
*/
pub fn get_system_data(&self, system_name: &str) -> Option<&PerformanceData> {
self.system_data.get(system_name)
}
/**
* 获取系统的统计信息
*/
pub fn get_system_stats(&self, system_name: &str) -> Option<&PerformanceStats> {
self.system_stats.get(system_name)
}
/**
* 获取所有系统的性能数据
*/
pub fn get_all_system_data(&self) -> &FxHashMap<String, PerformanceData> {
&self.system_data
}
/**
* 获取所有系统的统计信息
*/
pub fn get_all_system_stats(&self) -> &FxHashMap<String, PerformanceStats> {
&self.system_stats
}
/**
* 获取性能报告
*/
pub fn get_performance_report(&self) -> String {
if !self.is_enabled {
return "Performance monitoring is disabled.".to_string();
}
let mut lines = Vec::new();
lines.push("=== ECS Performance Report ===".to_string());
lines.push("".to_string());
// 按平均执行时间排序
let mut sorted_systems: Vec<_> = self.system_stats.iter().collect();
sorted_systems.sort_by(|a, b| b.1.average_time.partial_cmp(&a.1.average_time).unwrap());
for (system_name, stats) in sorted_systems {
if let Some(data) = self.system_data.get(system_name) {
lines.push(format!("System: {}", system_name));
lines.push(format!(" Current: {:.2}ms ({} entities)", data.execution_time, data.entity_count));
lines.push(format!(" Average: {:.2}ms", stats.average_time));
lines.push(format!(" Min/Max: {:.2}ms / {:.2}ms", stats.min_time, stats.max_time));
lines.push(format!(" Total: {:.2}ms ({} calls)", stats.total_time, stats.execution_count));
if data.average_time_per_entity > 0.0 {
lines.push(format!(" Per Entity: {:.4}ms", data.average_time_per_entity));
}
lines.push("".to_string());
}
}
// 总体统计
let total_current_time: f64 = self.system_data.values()
.map(|data| data.execution_time)
.sum();
lines.push(format!("Total Frame Time: {:.2}ms", total_current_time));
lines.push(format!("Systems Count: {}", self.system_data.len()));
lines.push(format!("Current FPS: {:.1}", self.current_fps));
lines.join("\n")
}
/**
* 获取性能警告
*/
pub fn get_performance_warnings(&self, threshold_ms: Option<f64>) -> Vec<String> {
let threshold = threshold_ms.unwrap_or(16.67); // 默认60fps阈值
let mut warnings = Vec::new();
for (system_name, data) in &self.system_data {
if data.execution_time > threshold {
warnings.push(format!("{}: {:.2}ms (>{:.0}ms)",
system_name, data.execution_time, threshold));
}
}
warnings
}
/**
* 获取所有警告
*/
pub fn get_warnings(&self) -> &[PerformanceWarning] {
&self.warnings
}
/**
* 清除所有警告
*/
pub fn clear_warnings(&mut self) {
self.warnings.clear();
}
/**
* 重置所有性能数据
*/
pub fn reset(&mut self) {
self.system_data.clear();
self.system_stats.clear();
self.warnings.clear();
}
/**
* 重置指定系统的性能数据
*/
pub fn reset_system(&mut self, system_name: &str) {
self.system_data.remove(system_name);
self.system_stats.remove(system_name);
}
/**
* 设置最大保留样本数
*/
pub fn set_max_recent_samples(&mut self, max_samples: usize) {
self.max_recent_samples = max_samples;
// 裁剪现有数据
for stats in self.system_stats.values_mut() {
while stats.recent_times.len() > max_samples {
stats.recent_times.pop_front();
}
}
}
/**
* 设置性能阈值
*/
pub fn set_thresholds(&mut self, thresholds: PerformanceThresholds) {
self.thresholds = thresholds;
}
/**
* 获取性能阈值
*/
pub fn get_thresholds(&self) -> &PerformanceThresholds {
&self.thresholds
}
/**
* 更新FPS
*/
pub fn update_fps(&mut self) {
let now = Instant::now();
if let Some(last_time) = self.last_frame_time {
let frame_time = now.duration_since(last_time).as_secs_f64() * 1000.0;
self.fps_history.push_back(1000.0 / frame_time);
// 保持历史记录在合理范围内
if self.fps_history.len() > self.max_recent_samples {
self.fps_history.pop_front();
}
// 每秒更新一次平均FPS
let current_time = current_timestamp();
if current_time - self.last_fps_update > self.fps_update_interval {
if !self.fps_history.is_empty() {
self.current_fps = self.fps_history.iter().sum::<f64>() / self.fps_history.len() as f64;
}
self.last_fps_update = current_time;
}
}
self.last_frame_time = Some(now);
self.frame_count += 1;
}
/**
* 获取当前FPS
*/
pub fn get_current_fps(&self) -> f64 {
self.current_fps
}
/**
* 获取平均FPS
*/
pub fn get_average_fps(&self) -> f64 {
if self.fps_history.is_empty() {
60.0
} else {
self.fps_history.iter().sum::<f64>() / self.fps_history.len() as f64
}
}
}
// 辅助函数
/**
* 获取当前时间戳(毫秒)
*/
fn current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread;
use std::time::Duration;
#[test]
fn test_performance_monitor_creation() {
let monitor = PerformanceMonitor::new();
assert!(!monitor.enabled());
assert_eq!(monitor.get_current_fps(), 60.0);
assert!(monitor.get_all_system_data().is_empty());
}
#[test]
fn test_performance_monitor_enable_disable() {
let mut monitor = PerformanceMonitor::new();
assert!(!monitor.enabled());
monitor.enable();
assert!(monitor.enabled());
monitor.disable();
assert!(!monitor.enabled());
}
#[test]
fn test_performance_monitoring_disabled() {
let mut monitor = PerformanceMonitor::new();
let start_time = monitor.start_monitoring("TestSystem");
assert!(start_time.is_none());
monitor.end_monitoring("TestSystem", start_time, 10);
assert!(monitor.get_system_data("TestSystem").is_none());
}
#[test]
fn test_performance_monitoring_enabled() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
let start_time = monitor.start_monitoring("TestSystem");
assert!(start_time.is_some());
thread::sleep(Duration::from_millis(10));
monitor.end_monitoring("TestSystem", start_time, 5);
let data = monitor.get_system_data("TestSystem");
assert!(data.is_some());
let data = data.unwrap();
assert_eq!(data.name, "TestSystem");
assert_eq!(data.entity_count, 5);
assert!(data.execution_time >= 10.0);
assert!(data.average_time_per_entity > 0.0);
}
#[test]
fn test_performance_stats_update() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
// 模拟多次执行
for i in 0..3 {
let start_time = monitor.start_monitoring("TestSystem");
thread::sleep(Duration::from_millis(5 + i)); // 不同的执行时间
monitor.end_monitoring("TestSystem", start_time, 10);
}
let stats = monitor.get_system_stats("TestSystem");
assert!(stats.is_some());
let stats = stats.unwrap();
assert_eq!(stats.execution_count, 3);
assert!(stats.total_time > 0.0);
assert!(stats.average_time > 0.0);
assert!(stats.min_time > 0.0);
assert!(stats.max_time > 0.0);
assert_eq!(stats.recent_times.len(), 3);
}
#[test]
fn test_performance_warnings() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
// 设置较低的阈值以触发警告
let mut thresholds = PerformanceThresholds::default();
thresholds.execution_time.warning = 1.0;
thresholds.execution_time.critical = 2.0;
monitor.set_thresholds(thresholds);
let start_time = monitor.start_monitoring("TestSystem");
thread::sleep(Duration::from_millis(5)); // 足够触发警告
monitor.end_monitoring("TestSystem", start_time, 10);
let warnings = monitor.get_warnings();
assert!(!warnings.is_empty());
assert_eq!(warnings[0].system_name, "TestSystem");
assert_eq!(warnings[0].warning_type, PerformanceWarningType::HighExecutionTime);
}
#[test]
fn test_performance_report() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
let start_time = monitor.start_monitoring("TestSystem");
thread::sleep(Duration::from_millis(5));
monitor.end_monitoring("TestSystem", start_time, 10);
let report = monitor.get_performance_report();
assert!(report.contains("ECS Performance Report"));
assert!(report.contains("TestSystem"));
}
#[test]
fn test_fps_monitoring() {
let mut monitor = PerformanceMonitor::new();
// 模拟几帧
for _ in 0..3 {
monitor.update_fps();
thread::sleep(Duration::from_millis(16)); // ~60fps
}
let fps = monitor.get_current_fps();
assert!(fps > 0.0);
}
#[test]
fn test_reset_functionality() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
let start_time = monitor.start_monitoring("TestSystem");
monitor.end_monitoring("TestSystem", start_time, 10);
assert!(monitor.get_system_data("TestSystem").is_some());
monitor.reset();
assert!(monitor.get_system_data("TestSystem").is_none());
assert!(monitor.get_warnings().is_empty());
}
#[test]
fn test_max_recent_samples() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
monitor.set_max_recent_samples(2);
// 执行3次但只应该保留最近2次的数据
for _ in 0..3 {
let start_time = monitor.start_monitoring("TestSystem");
monitor.end_monitoring("TestSystem", start_time, 10);
}
let stats = monitor.get_system_stats("TestSystem").unwrap();
assert_eq!(stats.recent_times.len(), 2);
assert_eq!(stats.execution_count, 3); // 总次数应该还是3
}
#[test]
fn test_system_reset() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
let start_time1 = monitor.start_monitoring("TestSystem1");
monitor.end_monitoring("TestSystem1", start_time1, 10);
let start_time2 = monitor.start_monitoring("TestSystem2");
monitor.end_monitoring("TestSystem2", start_time2, 20);
assert!(monitor.get_system_data("TestSystem1").is_some());
assert!(monitor.get_system_data("TestSystem2").is_some());
monitor.reset_system("TestSystem1");
assert!(monitor.get_system_data("TestSystem1").is_none());
assert!(monitor.get_system_data("TestSystem2").is_some());
}
#[test]
fn test_percentile_calculations() {
let mut monitor = PerformanceMonitor::new();
monitor.enable();
// 添加一些已知的执行时间
let times = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];
for &time in &times {
// 直接设置执行时间进行测试
monitor.update_stats("TestSystem", time);
}
let stats = monitor.get_system_stats("TestSystem").unwrap();
// 95%应该是9.5左右99%应该是9.9左右
assert!(stats.percentile_95 >= 9.0);
assert!(stats.percentile_99 >= 9.0);
// 标准差应该大于0
assert!(stats.standard_deviation > 0.0);
}
}

View File

@@ -0,0 +1,871 @@
use rustc_hash::FxHashMap;
use std::any::Any;
/**
* 可池化对象trait
*/
pub trait Poolable: Send + Sync {
/**
* 重置对象状态,准备重用
*/
fn reset(&mut self);
/**
* 获取对象的估算大小(字节)
*/
fn estimated_size(&self) -> usize {
std::mem::size_of_val(self)
}
}
/**
* 对象池统计信息
*/
#[derive(Debug, Clone)]
pub struct PoolStats {
/// 池中对象数量
pub size: usize,
/// 池的最大大小
pub max_size: usize,
/// 总共创建的对象数量
pub total_created: u64,
/// 总共获取的次数
pub total_obtained: u64,
/// 总共释放的次数
pub total_released: u64,
/// 命中率(从池中获取的比例)
pub hit_rate: f64,
/// 内存使用估算(字节)
pub estimated_memory_usage: usize,
}
impl Default for PoolStats {
fn default() -> Self {
Self {
size: 0,
max_size: 0,
total_created: 0,
total_obtained: 0,
total_released: 0,
hit_rate: 0.0,
estimated_memory_usage: 0,
}
}
}
/**
* 高性能通用对象池
* 支持任意类型的对象池化,包含详细的统计信息
*/
pub struct Pool<T: Poolable> {
/// 池中的对象
objects: Vec<T>,
/// 创建对象的函数
create_fn: Box<dyn Fn() -> T + Send + Sync>,
/// 池的最大大小
max_size: usize,
/// 统计信息
stats: PoolStats,
/// 估算的单个对象大小
object_size: usize,
}
impl<T: Poolable> Pool<T> {
/**
* 创建新的对象池
*/
pub fn new<F>(create_fn: F, max_size: usize, estimated_object_size: usize) -> Self
where
F: Fn() -> T + Send + Sync + 'static,
{
Self {
objects: Vec::new(),
create_fn: Box::new(create_fn),
max_size,
stats: PoolStats {
max_size,
..Default::default()
},
object_size: estimated_object_size,
}
}
/**
* 从池中获取对象
*/
pub fn obtain(&mut self) -> T {
self.stats.total_obtained += 1;
if let Some(mut obj) = self.objects.pop() {
self.stats.size -= 1;
self.update_hit_rate();
self.update_memory_usage();
obj.reset(); // 重置对象状态
obj
} else {
// 池中没有可用对象,创建新对象
self.stats.total_created += 1;
self.update_hit_rate();
(self.create_fn)()
}
}
/**
* 释放对象回池中
*/
pub fn release(&mut self, mut obj: T) {
self.stats.total_released += 1;
// 如果池未满,将对象放回池中
if self.stats.size < self.max_size {
obj.reset();
self.objects.push(obj);
self.stats.size += 1;
self.update_memory_usage();
}
// 如果池已满让对象被drop
}
/**
* 获取池统计信息
*/
pub fn get_stats(&self) -> &PoolStats {
&self.stats
}
/**
* 清空池
*/
pub fn clear(&mut self) {
self.objects.clear();
self.stats.size = 0;
self.update_memory_usage();
}
/**
* 压缩池(移除多余的对象)
*/
pub fn compact(&mut self, target_size: Option<usize>) {
let target = target_size.unwrap_or(self.objects.len() / 2);
while self.objects.len() > target {
self.objects.pop();
self.stats.size -= 1;
}
self.update_memory_usage();
}
/**
* 预填充池
*/
pub fn prewarm(&mut self, count: usize) {
let actual_count = count.min(self.max_size - self.objects.len());
for _ in 0..actual_count {
let mut obj = (self.create_fn)();
obj.reset();
self.objects.push(obj);
self.stats.total_created += 1;
self.stats.size += 1;
}
self.update_memory_usage();
}
/**
* 设置最大池大小
*/
pub fn set_max_size(&mut self, max_size: usize) {
self.max_size = max_size;
self.stats.max_size = max_size;
// 如果当前池大小超过新的最大值,进行压缩
if self.objects.len() > max_size {
self.compact(Some(max_size));
}
}
/**
* 获取池中可用对象数量
*/
pub fn get_available_count(&self) -> usize {
self.objects.len()
}
/**
* 检查池是否为空
*/
pub fn is_empty(&self) -> bool {
self.objects.is_empty()
}
/**
* 检查池是否已满
*/
pub fn is_full(&self) -> bool {
self.objects.len() >= self.max_size
}
/**
* 获取池的最大大小
*/
pub fn max_size(&self) -> usize {
self.max_size
}
/**
* 更新命中率
*/
fn update_hit_rate(&mut self) {
if self.stats.total_obtained == 0 {
self.stats.hit_rate = 0.0;
} else {
let hits = self.stats.total_obtained - self.stats.total_created;
self.stats.hit_rate = hits as f64 / self.stats.total_obtained as f64;
}
}
/**
* 更新内存使用估算
*/
fn update_memory_usage(&mut self) {
self.stats.estimated_memory_usage = self.stats.size * self.object_size;
}
}
/**
* Pool trait object for heterogeneous storage
*/
trait AnyPool: Send + Sync {
fn clear(&mut self);
fn compact(&mut self);
fn get_stats(&self) -> PoolStats;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T: Poolable + 'static> AnyPool for Pool<T> {
fn clear(&mut self) {
Pool::clear(self);
}
fn compact(&mut self) {
Pool::compact(self, None);
}
fn get_stats(&self) -> PoolStats {
self.stats.clone()
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 池管理器
* 统一管理所有对象池
*/
pub struct PoolManager {
/// 池映射
pools: FxHashMap<String, Box<dyn AnyPool>>,
/// 自动压缩间隔(毫秒)
auto_compact_interval: u64,
/// 上次压缩时间
last_compact_time: u64,
}
impl PoolManager {
/**
* 创建新的池管理器
*/
pub fn new() -> Self {
Self {
pools: FxHashMap::default(),
auto_compact_interval: 60000, // 60秒
last_compact_time: 0,
}
}
/**
* 注册池
*/
pub fn register_pool<T: Poolable + 'static>(&mut self, name: String, pool: Pool<T>) {
self.pools.insert(name, Box::new(pool));
}
/**
* 获取池
*/
pub fn get_pool<T: Poolable + 'static>(&mut self, name: &str) -> Option<&mut Pool<T>> {
if let Some(pool) = self.pools.get_mut(name) {
pool.as_any_mut().downcast_mut::<Pool<T>>()
} else {
None
}
}
/**
* 创建或获取池
*/
pub fn create_pool<T, F>(
&mut self,
name: String,
create_fn: F,
max_size: usize,
estimated_object_size: usize,
) -> &mut Pool<T>
where
T: Poolable + 'static,
F: Fn() -> T + Send + Sync + 'static,
{
if !self.pools.contains_key(&name) {
let pool = Pool::new(create_fn, max_size, estimated_object_size);
self.pools.insert(name.clone(), Box::new(pool));
}
self.get_pool(&name).unwrap()
}
/**
* 更新池管理器(应在游戏循环中调用)
*/
pub fn update(&mut self) {
let now = current_timestamp();
if now - self.last_compact_time > self.auto_compact_interval {
self.compact_all_pools();
self.last_compact_time = now;
}
}
/**
* 移除池
*/
pub fn remove_pool(&mut self, name: &str) -> bool {
if let Some(mut pool) = self.pools.remove(name) {
pool.clear();
true
} else {
false
}
}
/**
* 获取所有池名称
*/
pub fn get_pool_names(&self) -> Vec<String> {
self.pools.keys().cloned().collect()
}
/**
* 获取池数量
*/
pub fn get_pool_count(&self) -> usize {
self.pools.len()
}
/**
* 压缩所有池
*/
pub fn compact_all_pools(&mut self) {
for pool in self.pools.values_mut() {
pool.compact();
}
}
/**
* 清空所有池
*/
pub fn clear_all_pools(&mut self) {
for pool in self.pools.values_mut() {
pool.clear();
}
}
/**
* 获取所有池的统计信息
*/
pub fn get_all_stats(&self) -> FxHashMap<String, PoolStats> {
let mut stats = FxHashMap::default();
for (name, pool) in &self.pools {
stats.insert(name.clone(), pool.get_stats());
}
stats
}
/**
* 获取总体统计信息
*/
pub fn get_global_stats(&self) -> PoolStats {
let mut total_size = 0;
let mut total_max_size = 0;
let mut total_created = 0;
let mut total_obtained = 0;
let mut total_released = 0;
let mut total_memory_usage = 0;
for pool in self.pools.values() {
let stats = pool.get_stats();
total_size += stats.size;
total_max_size += stats.max_size;
total_created += stats.total_created;
total_obtained += stats.total_obtained;
total_released += stats.total_released;
total_memory_usage += stats.estimated_memory_usage;
}
let hit_rate = if total_obtained == 0 {
0.0
} else {
(total_obtained - total_created) as f64 / total_obtained as f64
};
PoolStats {
size: total_size,
max_size: total_max_size,
total_created,
total_obtained,
total_released,
hit_rate,
estimated_memory_usage: total_memory_usage,
}
}
/**
* 获取格式化的统计信息字符串
*/
pub fn get_stats_string(&self) -> String {
let mut lines = vec![
"=== Pool Manager Statistics ===".to_string(),
"".to_string(),
];
if self.pools.is_empty() {
lines.push("No pools registered".to_string());
return lines.join("\n");
}
let global_stats = self.get_global_stats();
lines.push(format!("Total Pools: {}", self.pools.len()));
lines.push(format!("Global Hit Rate: {:.1}%", global_stats.hit_rate * 100.0));
lines.push(format!(
"Global Memory Usage: {:.1} KB",
global_stats.estimated_memory_usage as f64 / 1024.0
));
lines.push("".to_string());
for (name, pool) in &self.pools {
let stats = pool.get_stats();
lines.push(format!("{}:", name));
lines.push(format!(" Size: {}/{}", stats.size, stats.max_size));
lines.push(format!(" Hit Rate: {:.1}%", stats.hit_rate * 100.0));
lines.push(format!(
" Memory: {:.1} KB",
stats.estimated_memory_usage as f64 / 1024.0
));
lines.push("".to_string());
}
lines.join("\n")
}
/**
* 设置自动压缩间隔
*/
pub fn set_auto_compact_interval(&mut self, interval_ms: u64) {
self.auto_compact_interval = interval_ms;
}
/**
* 预填充所有池
*/
pub fn prewarm_all_pools(&mut self) {
for pool in self.pools.values_mut() {
let stats = pool.get_stats();
let prewarm_count = (stats.max_size as f64 * 0.2) as usize; // 预填充20%
// 注意这里需要访问具体的池类型来调用prewarm
// 在实际使用中可能需要为AnyPool trait添加prewarm方法
}
}
/**
* 重置池管理器
*/
pub fn reset(&mut self) {
self.clear_all_pools();
self.pools.clear();
self.last_compact_time = 0;
}
}
impl Default for PoolManager {
fn default() -> Self {
Self::new()
}
}
// 辅助函数
fn current_timestamp() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
#[cfg(test)]
mod tests {
use super::*;
// 测试对象
#[derive(Debug, Clone)]
struct TestObject {
value: i32,
data: String,
}
impl TestObject {
fn new() -> Self {
Self {
value: 0,
data: String::new(),
}
}
fn with_value(value: i32) -> Self {
Self {
value,
data: format!("data_{}", value),
}
}
}
impl Poolable for TestObject {
fn reset(&mut self) {
self.value = 0;
self.data.clear();
}
fn estimated_size(&self) -> usize {
std::mem::size_of::<Self>() + self.data.capacity()
}
}
#[test]
fn test_pool_creation() {
let pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
assert_eq!(pool.get_available_count(), 0);
assert_eq!(pool.max_size(), 10);
assert!(pool.is_empty());
assert!(!pool.is_full());
}
#[test]
fn test_pool_obtain_release() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
// 获取对象(池为空,应该创建新对象)
let obj = pool.obtain();
assert_eq!(obj.value, 0);
let stats = pool.get_stats();
assert_eq!(stats.total_created, 1);
assert_eq!(stats.total_obtained, 1);
// 释放对象
pool.release(obj);
let stats = pool.get_stats();
assert_eq!(stats.total_released, 1);
assert_eq!(stats.size, 1);
assert_eq!(pool.get_available_count(), 1);
}
#[test]
fn test_pool_reuse() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
// 创建并释放一个对象
let mut obj = pool.obtain();
obj.value = 42;
obj.data = "test".to_string();
pool.release(obj);
// 再次获取应该得到重置后的对象
let obj = pool.obtain();
assert_eq!(obj.value, 0);
assert!(obj.data.is_empty());
let stats = pool.get_stats();
assert_eq!(stats.total_created, 1); // 只创建了一次
assert_eq!(stats.total_obtained, 2); // 获取了两次
assert!(stats.hit_rate > 0.0); // 有命中率
}
#[test]
fn test_pool_max_size() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 2, 64);
// 释放3个对象但池最大大小为2
pool.release(TestObject::new());
pool.release(TestObject::new());
pool.release(TestObject::new()); // 这个应该被丢弃
assert_eq!(pool.get_available_count(), 2);
assert!(pool.is_full());
}
#[test]
fn test_pool_prewarm() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
pool.prewarm(5);
assert_eq!(pool.get_available_count(), 5);
let stats = pool.get_stats();
assert_eq!(stats.total_created, 5);
assert_eq!(stats.size, 5);
}
#[test]
fn test_pool_compact() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
// 预填充
pool.prewarm(8);
assert_eq!(pool.get_available_count(), 8);
// 压缩到一半
pool.compact(Some(4));
assert_eq!(pool.get_available_count(), 4);
// 默认压缩
pool.compact(None);
assert_eq!(pool.get_available_count(), 2);
}
#[test]
fn test_pool_clear() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
pool.prewarm(5);
assert_eq!(pool.get_available_count(), 5);
pool.clear();
assert_eq!(pool.get_available_count(), 0);
assert!(pool.is_empty());
}
#[test]
fn test_pool_set_max_size() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
pool.prewarm(8);
assert_eq!(pool.get_available_count(), 8);
// 减小最大大小应该自动压缩
pool.set_max_size(5);
assert_eq!(pool.max_size(), 5);
assert_eq!(pool.get_available_count(), 5);
}
#[test]
fn test_pool_stats() {
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
// 获取和释放一些对象
let obj1 = pool.obtain();
let obj2 = pool.obtain();
pool.release(obj1);
let obj3 = pool.obtain(); // 应该重用obj1
pool.release(obj2);
pool.release(obj3);
let stats = pool.get_stats();
assert_eq!(stats.total_created, 2);
assert_eq!(stats.total_obtained, 3);
assert_eq!(stats.total_released, 3);
assert!(stats.hit_rate > 0.0);
assert_eq!(stats.size, 2);
}
#[test]
fn test_pool_manager_creation() {
let manager = PoolManager::new();
assert_eq!(manager.get_pool_count(), 0);
assert!(manager.get_pool_names().is_empty());
}
#[test]
fn test_pool_manager_register_get() {
let mut manager = PoolManager::new();
let pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
manager.register_pool("test_objects".to_string(), pool);
assert_eq!(manager.get_pool_count(), 1);
let retrieved_pool = manager.get_pool::<TestObject>("test_objects");
assert!(retrieved_pool.is_some());
let non_existent = manager.get_pool::<TestObject>("non_existent");
assert!(non_existent.is_none());
}
#[test]
fn test_pool_manager_create_pool() {
let mut manager = PoolManager::new();
let pool = manager.create_pool(
"test_objects".to_string(),
TestObject::new,
10,
64,
);
assert_eq!(pool.max_size(), 10);
assert_eq!(manager.get_pool_count(), 1);
}
#[test]
fn test_pool_manager_remove_pool() {
let mut manager = PoolManager::new();
let pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
manager.register_pool("test_objects".to_string(), pool);
assert_eq!(manager.get_pool_count(), 1);
assert!(manager.remove_pool("test_objects"));
assert_eq!(manager.get_pool_count(), 0);
assert!(!manager.remove_pool("non_existent"));
}
#[test]
fn test_pool_manager_global_stats() {
let mut manager = PoolManager::new();
let pool1: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
let pool2: Pool<TestObject> = Pool::new(TestObject::new, 20, 128);
manager.register_pool("pool1".to_string(), pool1);
manager.register_pool("pool2".to_string(), pool2);
let global_stats = manager.get_global_stats();
assert_eq!(global_stats.max_size, 30); // 10 + 20
}
#[test]
fn test_pool_manager_clear_all() {
let mut manager = PoolManager::new();
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
pool.prewarm(5);
manager.register_pool("test_objects".to_string(), pool);
manager.clear_all_pools();
if let Some(pool) = manager.get_pool::<TestObject>("test_objects") {
assert!(pool.is_empty());
}
}
#[test]
fn test_pool_manager_compact_all() {
let mut manager = PoolManager::new();
let mut pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
pool.prewarm(8);
manager.register_pool("test_objects".to_string(), pool);
manager.compact_all_pools();
if let Some(pool) = manager.get_pool::<TestObject>("test_objects") {
assert!(pool.get_available_count() <= 4); // 压缩后应该减少
}
}
#[test]
fn test_pool_manager_stats_string() {
let mut manager = PoolManager::new();
let pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
manager.register_pool("test_objects".to_string(), pool);
let stats_string = manager.get_stats_string();
assert!(stats_string.contains("Pool Manager Statistics"));
assert!(stats_string.contains("test_objects"));
}
#[test]
fn test_pool_manager_reset() {
let mut manager = PoolManager::new();
let pool: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
manager.register_pool("test_objects".to_string(), pool);
assert_eq!(manager.get_pool_count(), 1);
manager.reset();
assert_eq!(manager.get_pool_count(), 0);
assert_eq!(manager.last_compact_time, 0);
}
// 测试不同类型的Poolable对象
#[derive(Debug)]
struct AnotherTestObject {
id: u32,
active: bool,
}
impl AnotherTestObject {
fn new() -> Self {
Self {
id: 0,
active: false,
}
}
}
impl Poolable for AnotherTestObject {
fn reset(&mut self) {
self.id = 0;
self.active = false;
}
}
#[test]
fn test_pool_manager_multiple_types() {
let mut manager = PoolManager::new();
let pool1: Pool<TestObject> = Pool::new(TestObject::new, 10, 64);
let pool2: Pool<AnotherTestObject> = Pool::new(AnotherTestObject::new, 5, 32);
manager.register_pool("test_objects".to_string(), pool1);
manager.register_pool("another_objects".to_string(), pool2);
assert_eq!(manager.get_pool_count(), 2);
let pool1 = manager.get_pool::<TestObject>("test_objects");
assert!(pool1.is_some());
let pool2 = manager.get_pool::<AnotherTestObject>("another_objects");
assert!(pool2.is_some());
// 尝试用错误的类型获取池
let wrong_pool = manager.get_pool::<AnotherTestObject>("test_objects");
assert!(wrong_pool.is_none());
}
}

View File

@@ -0,0 +1,238 @@
/**
* 高性能稀疏集合数据结构
*
* SparseSet是ECS系统中常用的数据结构提供O(1)的插入、删除和查找操作
* 同时支持密集数组迭代,非常适合存储稀疏的实体组件数据
*/
pub struct SparseSet {
/// 稀疏数组,索引到密集数组的映射
sparse: Vec<Option<usize>>,
/// 密集数组,存储实际的值
dense: Vec<u32>,
/// 当前元素数量
size: usize,
}
impl SparseSet {
/**
* 创建新的稀疏集合
*/
pub fn new() -> Self {
Self {
sparse: Vec::new(),
dense: Vec::new(),
size: 0,
}
}
/**
* 创建指定容量的稀疏集合
*/
pub fn with_capacity(sparse_capacity: usize, dense_capacity: usize) -> Self {
Self {
sparse: vec![None; sparse_capacity],
dense: Vec::with_capacity(dense_capacity),
size: 0,
}
}
/**
* 插入值
*/
pub fn insert(&mut self, value: u32) -> bool {
let sparse_index = value as usize;
// 确保稀疏数组足够大
if sparse_index >= self.sparse.len() {
self.sparse.resize(sparse_index + 1, None);
}
// 检查值是否已存在
if self.sparse[sparse_index].is_some() {
return false;
}
// 插入到密集数组
let dense_index = self.size;
if dense_index >= self.dense.len() {
self.dense.push(value);
} else {
self.dense[dense_index] = value;
}
// 建立稀疏数组映射
self.sparse[sparse_index] = Some(dense_index);
self.size += 1;
true
}
/**
* 移除值
*/
pub fn remove(&mut self, value: u32) -> bool {
let sparse_index = value as usize;
// 检查边界和存在性
if sparse_index >= self.sparse.len() {
return false;
}
let Some(dense_index) = self.sparse[sparse_index] else {
return false;
};
// 移除稀疏数组映射
self.sparse[sparse_index] = None;
// 将最后一个元素移动到被删除位置(保持密集性)
let last_index = self.size - 1;
if dense_index != last_index {
let last_value = self.dense[last_index];
self.dense[dense_index] = last_value;
// 更新被移动元素的稀疏数组映射
self.sparse[last_value as usize] = Some(dense_index);
}
self.size -= 1;
true
}
/**
* 检查值是否存在
*/
pub fn contains(&self, value: u32) -> bool {
let sparse_index = value as usize;
sparse_index < self.sparse.len() && self.sparse[sparse_index].is_some()
}
/**
* 获取元素数量
*/
pub fn len(&self) -> usize {
self.size
}
/**
* 检查是否为空
*/
pub fn is_empty(&self) -> bool {
self.size == 0
}
/**
* 清空集合
*/
pub fn clear(&mut self) {
self.sparse.clear();
self.dense.clear();
self.size = 0;
}
/**
* 获取密集数组的引用
*/
pub fn dense(&self) -> &[u32] {
&self.dense[0..self.size]
}
/**
* 获取密集数组的可变引用
*/
pub fn dense_mut(&mut self) -> &mut [u32] {
&mut self.dense[0..self.size]
}
/**
* 迭代所有值
*/
pub fn iter(&self) -> impl Iterator<Item = u32> + '_ {
self.dense[0..self.size].iter().copied()
}
/**
* 批量插入
*/
pub fn insert_batch(&mut self, values: &[u32]) {
for &value in values {
self.insert(value);
}
}
/**
* 获取值在密集数组中的索引
*/
pub fn get_dense_index(&self, value: u32) -> Option<usize> {
let sparse_index = value as usize;
if sparse_index < self.sparse.len() {
self.sparse[sparse_index]
} else {
None
}
}
/**
* 预分配容量
*/
pub fn reserve(&mut self, sparse_capacity: usize, dense_capacity: usize) {
if sparse_capacity > self.sparse.len() {
self.sparse.resize(sparse_capacity, None);
}
if dense_capacity > self.dense.capacity() {
self.dense.reserve(dense_capacity - self.dense.capacity());
}
}
/**
* 与另一个稀疏集合取交集
*/
pub fn intersection(&self, other: &SparseSet) -> SparseSet {
let mut result = SparseSet::new();
for value in self.iter() {
if other.contains(value) {
result.insert(value);
}
}
result
}
/**
* 与另一个稀疏集合取并集
*/
pub fn union(&self, other: &SparseSet) -> SparseSet {
let mut result = SparseSet::new();
// 添加当前集合的所有元素
for value in self.iter() {
result.insert(value);
}
// 添加另一个集合的所有元素
for value in other.iter() {
result.insert(value);
}
result
}
}
impl Default for SparseSet {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for SparseSet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SparseSet")
.field("size", &self.size)
.field("sparse_len", &self.sparse.len())
.field("dense_elements", &self.dense[0..self.size].to_vec())
.finish()
}
}

View File

@@ -0,0 +1,124 @@
use std::sync::{Mutex, OnceLock};
/**
* 时间管理工具类
* 提供游戏时间相关的功能,包括帧时间、总时间、时间缩放等
*/
pub struct Time {
/// 上一帧到当前帧的时间间隔(秒)
delta_time: f64,
/// 未缩放的帧时间间隔(秒)
unscaled_delta_time: f64,
/// 游戏开始以来的总时间(秒)
total_time: f64,
/// 未缩放的总时间(秒)
unscaled_total_time: f64,
/// 时间缩放比例
time_scale: f64,
/// 当前帧数
frame_count: u64,
}
impl Time {
pub fn new() -> Self {
Self {
delta_time: 0.0,
unscaled_delta_time: 0.0,
total_time: 0.0,
unscaled_total_time: 0.0,
time_scale: 1.0,
frame_count: 0,
}
}
/**
* 获取全局Time实例
*/
pub fn instance() -> &'static Mutex<Time> {
static TIME: OnceLock<Mutex<Time>> = OnceLock::new();
TIME.get_or_init(|| Mutex::new(Time::new()))
}
/**
* 使用外部引擎提供的deltaTime更新时间信息
*/
pub fn update(delta_time: f64) {
let mut time = Self::instance().lock().unwrap();
time.unscaled_delta_time = delta_time;
time.delta_time = delta_time * time.time_scale;
// 更新总时间
time.unscaled_total_time += time.unscaled_delta_time;
time.total_time += time.delta_time;
// 更新帧数
time.frame_count += 1;
}
/**
* 获取帧时间间隔
*/
pub fn delta_time() -> f64 {
Self::instance().lock().unwrap().delta_time
}
/**
* 获取未缩放的帧时间间隔
*/
pub fn unscaled_delta_time() -> f64 {
Self::instance().lock().unwrap().unscaled_delta_time
}
/**
* 获取总时间
*/
pub fn total_time() -> f64 {
Self::instance().lock().unwrap().total_time
}
/**
* 获取未缩放的总时间
*/
pub fn unscaled_total_time() -> f64 {
Self::instance().lock().unwrap().unscaled_total_time
}
/**
* 获取时间缩放比例
*/
pub fn time_scale() -> f64 {
Self::instance().lock().unwrap().time_scale
}
/**
* 设置时间缩放比例
*/
pub fn set_time_scale(scale: f64) {
Self::instance().lock().unwrap().time_scale = scale;
}
/**
* 获取当前帧数
*/
pub fn frame_count() -> u64 {
Self::instance().lock().unwrap().frame_count
}
/**
* 重置时间
*/
pub fn reset() {
let mut time = Self::instance().lock().unwrap();
time.delta_time = 0.0;
time.unscaled_delta_time = 0.0;
time.total_time = 0.0;
time.unscaled_total_time = 0.0;
time.time_scale = 1.0;
time.frame_count = 0;
}
}

View File

@@ -0,0 +1,665 @@
use crate::utils::Time;
use std::any::Any;
/**
* 定时器回调函数类型
*/
pub type TimerCallback = Box<dyn FnMut(&mut dyn TimerContext) + Send + Sync>;
/**
* 定时器上下文trait
* 用于提供回调函数访问的上下文数据
*/
pub trait TimerContext: Send + Sync {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
/**
* 默认的空上下文实现
*/
#[derive(Debug)]
pub struct EmptyContext;
impl TimerContext for EmptyContext {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 定时器接口trait
*/
pub trait ITimer {
/**
* 停止此计时器再次运行。这对非重复计时器没有影响。
*/
fn stop(&mut self);
/**
* 将计时器的运行时间重置为0
*/
fn reset(&mut self);
/**
* 返回上下文
*/
fn get_context(&self) -> &dyn TimerContext;
/**
* 返回可变上下文
*/
fn get_context_mut(&mut self) -> &mut dyn TimerContext;
/**
* 检查定时器是否已完成
*/
fn is_done(&self) -> bool;
/**
* 获取已运行的时间
*/
fn elapsed_time(&self) -> f64;
}
/**
* 定时器实现
*/
pub struct Timer {
/// 上下文数据
context: Box<dyn TimerContext>,
/// 定时器间隔时间(秒)
time_in_seconds: f64,
/// 是否重复执行
repeats: bool,
/// 回调函数
on_time: Option<TimerCallback>,
/// 是否已完成
is_done: bool,
/// 已运行时间
elapsed_time: f64,
}
impl Timer {
/**
* 创建新的定时器
*/
pub fn new() -> Self {
Self {
context: Box::new(EmptyContext),
time_in_seconds: 0.0,
repeats: false,
on_time: None,
is_done: false,
elapsed_time: 0.0,
}
}
/**
* 初始化定时器
*/
pub fn initialize<F>(
&mut self,
time_in_seconds: f64,
repeats: bool,
context: Box<dyn TimerContext>,
on_time: F,
) where
F: FnMut(&mut dyn TimerContext) + Send + Sync + 'static,
{
self.time_in_seconds = time_in_seconds;
self.repeats = repeats;
self.context = context;
self.on_time = Some(Box::new(on_time));
self.is_done = false;
self.elapsed_time = 0.0;
}
/**
* 使用简单回调初始化定时器
*/
pub fn initialize_simple<F>(
&mut self,
time_in_seconds: f64,
repeats: bool,
on_time: F,
) where
F: FnMut(&mut dyn TimerContext) + Send + Sync + 'static,
{
self.initialize(time_in_seconds, repeats, Box::new(EmptyContext), on_time);
}
/**
* 更新定时器状态
* 返回是否已完成
*/
pub fn tick(&mut self, delta_time: f64) -> bool {
if self.is_done {
return true;
}
self.elapsed_time += delta_time;
// 检查是否到达触发时间
if self.elapsed_time >= self.time_in_seconds {
if let Some(callback) = &mut self.on_time {
// 调用回调函数
callback(self.context.as_mut());
}
if self.repeats {
// 重复定时器,重置经过时间但保留超出部分
self.elapsed_time -= self.time_in_seconds;
} else {
// 一次性定时器,标记为完成
self.is_done = true;
}
}
self.is_done
}
/**
* 清理定时器资源
*/
pub fn unload(&mut self) {
self.on_time = None;
self.context = Box::new(EmptyContext);
}
}
impl Default for Timer {
fn default() -> Self {
Self::new()
}
}
impl ITimer for Timer {
fn stop(&mut self) {
self.is_done = true;
}
fn reset(&mut self) {
self.elapsed_time = 0.0;
self.is_done = false;
}
fn get_context(&self) -> &dyn TimerContext {
self.context.as_ref()
}
fn get_context_mut(&mut self) -> &mut dyn TimerContext {
self.context.as_mut()
}
fn is_done(&self) -> bool {
self.is_done
}
fn elapsed_time(&self) -> f64 {
self.elapsed_time
}
}
/**
* 定时器管理器
* 允许动作的延迟和重复执行
*/
pub struct TimerManager {
/// 活跃的定时器列表
timers: Vec<Timer>,
/// 管理器是否启用
enabled: bool,
}
impl TimerManager {
/**
* 创建新的定时器管理器
*/
pub fn new() -> Self {
Self {
timers: Vec::new(),
enabled: true,
}
}
/**
* 启用管理器
*/
pub fn enable(&mut self) {
self.enabled = true;
}
/**
* 禁用管理器
*/
pub fn disable(&mut self) {
self.enabled = false;
}
/**
* 检查管理器是否启用
*/
pub fn is_enabled(&self) -> bool {
self.enabled
}
/**
* 更新所有定时器
*/
pub fn update(&mut self, time: &Time) {
if !self.enabled {
return;
}
let delta_time = Time::delta_time();
// 从后向前遍历以安全地移除完成的定时器
let mut i = self.timers.len();
while i > 0 {
i -= 1;
if self.timers[i].tick(delta_time) {
self.timers[i].unload();
self.timers.remove(i);
}
}
}
/**
* 调度一个一次性或重复的计时器
*/
pub fn schedule<F>(
&mut self,
time_in_seconds: f64,
repeats: bool,
context: Box<dyn TimerContext>,
on_time: F,
) -> usize
where
F: FnMut(&mut dyn TimerContext) + Send + Sync + 'static,
{
let mut timer = Timer::new();
timer.initialize(time_in_seconds, repeats, context, on_time);
self.timers.push(timer);
self.timers.len() - 1 // 返回定时器的索引
}
/**
* 调度简单定时器(无上下文)
*/
pub fn schedule_simple<F>(
&mut self,
time_in_seconds: f64,
repeats: bool,
on_time: F,
) -> usize
where
F: FnMut(&mut dyn TimerContext) + Send + Sync + 'static,
{
self.schedule(time_in_seconds, repeats, Box::new(EmptyContext), on_time)
}
/**
* 停止指定索引的定时器
*/
pub fn stop_timer(&mut self, index: usize) -> bool {
if index < self.timers.len() {
self.timers[index].stop();
true
} else {
false
}
}
/**
* 重置指定索引的定时器
*/
pub fn reset_timer(&mut self, index: usize) -> bool {
if index < self.timers.len() {
self.timers[index].reset();
true
} else {
false
}
}
/**
* 获取活跃定时器数量
*/
pub fn active_timer_count(&self) -> usize {
self.timers.len()
}
/**
* 清除所有定时器
*/
pub fn clear(&mut self) {
for timer in &mut self.timers {
timer.unload();
}
self.timers.clear();
}
/**
* 获取指定索引的定时器
*/
pub fn get_timer(&self, index: usize) -> Option<&Timer> {
self.timers.get(index)
}
/**
* 获取指定索引的可变定时器
*/
pub fn get_timer_mut(&mut self, index: usize) -> Option<&mut Timer> {
self.timers.get_mut(index)
}
/**
* 移除所有已完成的定时器
*/
pub fn cleanup_completed(&mut self) {
self.timers.retain_mut(|timer| {
if timer.is_done() {
timer.unload();
false
} else {
true
}
});
}
}
impl Default for TimerManager {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
// 测试上下文
#[derive(Debug)]
struct TestContext {
pub value: i32,
pub name: String,
}
impl TimerContext for TestContext {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[test]
fn test_timer_creation() {
let timer = Timer::new();
assert!(!timer.is_done());
assert_eq!(timer.elapsed_time(), 0.0);
}
#[test]
fn test_timer_simple_initialization() {
let mut timer = Timer::new();
let mut callback_called = false;
timer.initialize_simple(1.0, false, move |_context| {
callback_called = true;
});
assert!(!timer.is_done());
assert_eq!(timer.elapsed_time(), 0.0);
}
#[test]
fn test_timer_tick_completion() {
let mut timer = Timer::new();
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
timer.initialize_simple(1.0, false, move |_context| {
*callback_count_clone.lock().unwrap() += 1;
});
// 第一次tick时间不够
assert!(!timer.tick(0.5));
assert!(!timer.is_done());
assert_eq!(timer.elapsed_time(), 0.5);
assert_eq!(*callback_count.lock().unwrap(), 0);
// 第二次tick时间足够
assert!(timer.tick(0.6));
assert!(timer.is_done());
assert_eq!(*callback_count.lock().unwrap(), 1);
}
#[test]
fn test_timer_repeat() {
let mut timer = Timer::new();
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
timer.initialize_simple(0.5, true, move |_context| {
*callback_count_clone.lock().unwrap() += 1;
});
// 多次tick测试重复执行
assert!(!timer.tick(0.6)); // 第一次触发
assert_eq!(*callback_count.lock().unwrap(), 1);
assert!(!timer.is_done());
assert!(!timer.tick(0.5)); // 第二次触发
assert_eq!(*callback_count.lock().unwrap(), 2);
assert!(!timer.is_done());
// 停止定时器
timer.stop();
assert!(timer.is_done());
}
#[test]
fn test_timer_reset() {
let mut timer = Timer::new();
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
timer.initialize_simple(1.0, false, move |_context| {
*callback_count_clone.lock().unwrap() += 1;
});
// 部分执行后重置
timer.tick(0.5);
assert_eq!(timer.elapsed_time(), 0.5);
timer.reset();
assert_eq!(timer.elapsed_time(), 0.0);
assert!(!timer.is_done());
// 重新执行
timer.tick(1.1);
assert_eq!(*callback_count.lock().unwrap(), 1);
assert!(timer.is_done());
}
#[test]
fn test_timer_with_context() {
let mut timer = Timer::new();
let context = TestContext {
value: 10,
name: "test".to_string(),
};
timer.initialize(1.0, false, Box::new(context), |context| {
if let Some(test_context) = context.as_any_mut().downcast_mut::<TestContext>() {
test_context.value += 5;
}
});
timer.tick(1.1);
let context = timer.get_context();
if let Some(test_context) = context.as_any().downcast_ref::<TestContext>() {
assert_eq!(test_context.value, 15);
assert_eq!(test_context.name, "test");
} else {
panic!("Context type mismatch");
}
}
#[test]
fn test_timer_manager_creation() {
let manager = TimerManager::new();
assert!(manager.enabled());
assert_eq!(manager.active_timer_count(), 0);
}
#[test]
fn test_timer_manager_schedule_simple() {
let mut manager = TimerManager::new();
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
let timer_id = manager.schedule_simple(1.0, false, move |_context| {
*callback_count_clone.lock().unwrap() += 1;
});
assert_eq!(manager.active_timer_count(), 1);
assert_eq!(timer_id, 0);
let time = Time::new();
manager.update(&time);
assert_eq!(*callback_count.lock().unwrap(), 0); // 时间不够
}
#[test]
fn test_timer_manager_schedule_with_context() {
let mut manager = TimerManager::new();
let context = TestContext {
value: 0,
name: "manager_test".to_string(),
};
manager.schedule(0.5, false, Box::new(context), |context| {
if let Some(test_context) = context.as_any_mut().downcast_mut::<TestContext>() {
test_context.value = 42;
}
});
assert_eq!(manager.active_timer_count(), 1);
}
#[test]
fn test_timer_manager_update() {
let mut manager = TimerManager::new();
let callback_count = Arc::new(Mutex::new(0));
let callback_count_clone = Arc::clone(&callback_count);
manager.schedule_simple(0.5, false, move |_context| {
*callback_count_clone.lock().unwrap() += 1;
});
// 创建一个模拟的时间对象
let mut time = Time::new();
// 第一次更新,时间不够
manager.update(&time);
assert_eq!(manager.active_timer_count(), 1);
assert_eq!(*callback_count.lock().unwrap(), 0);
// 手动设置delta_time来模拟时间流逝
// 注意:这里我们需要用实际的时间更新机制
// 在实际使用中Time对象会自动更新delta_time
}
#[test]
fn test_timer_manager_stop_timer() {
let mut manager = TimerManager::new();
let timer_id = manager.schedule_simple(1.0, true, |_context| {
// 回调函数
});
assert_eq!(manager.active_timer_count(), 1);
assert!(manager.stop_timer(timer_id));
assert!(!manager.stop_timer(999)); // 无效索引
// 定时器被停止但还在列表中
assert_eq!(manager.active_timer_count(), 1);
let time = Time::new();
manager.update(&time);
// 更新后被移除
// 注意需要足够的时间让tick返回true
}
#[test]
fn test_timer_manager_clear() {
let mut manager = TimerManager::new();
manager.schedule_simple(1.0, false, |_context| {});
manager.schedule_simple(2.0, true, |_context| {});
assert_eq!(manager.active_timer_count(), 2);
manager.clear();
assert_eq!(manager.active_timer_count(), 0);
}
#[test]
fn test_timer_manager_enable_disable() {
let mut manager = TimerManager::new();
assert!(manager.enabled());
manager.disable();
assert!(!manager.enabled());
manager.enable();
assert!(manager.enabled());
}
#[test]
fn test_timer_manager_cleanup_completed() {
let mut manager = TimerManager::new();
// 添加一个已完成的定时器
let timer_id = manager.schedule_simple(0.1, false, |_context| {});
// 手动标记为完成
if let Some(timer) = manager.get_timer_mut(timer_id) {
timer.stop();
}
assert_eq!(manager.active_timer_count(), 1);
manager.cleanup_completed();
assert_eq!(manager.active_timer_count(), 0);
}
#[test]
fn test_timer_manager_get_timer() {
let mut manager = TimerManager::new();
let timer_id = manager.schedule_simple(1.0, false, |_context| {});
assert!(manager.get_timer(timer_id).is_some());
assert!(manager.get_timer(999).is_none());
assert!(manager.get_timer_mut(timer_id).is_some());
assert!(manager.get_timer_mut(999).is_none());
}
}

View File

@@ -0,0 +1,802 @@
use std::any::Any;
use std::marker::PhantomData;
/**
* 可更新接口
* 当添加到组件时只要组件和实体被启用就会在每帧调用update方法
*/
pub trait IUpdatable: Send + Sync {
/**
* 检查是否启用
*/
fn is_enabled(&self) -> bool;
/**
* 获取更新顺序
*/
fn get_update_order(&self) -> i32;
/**
* 更新方法,每帧调用
*/
fn update(&mut self);
/**
* 转换为Any trait对象用于类型转换
*/
fn as_any(&self) -> &dyn Any;
/**
* 转换为可变的Any trait对象用于类型转换
*/
fn as_any_mut(&mut self) -> &mut dyn Any;
}
/**
* 用于比较组件更新排序的比较器
*/
pub struct IUpdatableComparer;
impl IUpdatableComparer {
/**
* 比较两个IUpdatable对象的更新顺序
*/
pub fn compare(a: &dyn IUpdatable, b: &dyn IUpdatable) -> std::cmp::Ordering {
a.get_update_order().cmp(&b.get_update_order())
}
}
/**
* 检查对象是否实现了IUpdatable接口
* 注意:此函数目前无法在运行时动态检查,仅作为编译时类型检查的辅助
*/
pub fn is_updatable<T: IUpdatable>(_obj: &T) -> bool {
true
}
/**
* 场景组件基类
* 附加到场景的组件,用于实现场景级别的功能
*/
pub struct SceneComponent {
/// 场景ID用于标识所属场景避免原始指针的线程安全问题
pub scene_id: Option<u32>,
/// 更新顺序
pub update_order: i32,
/// 是否启用
enabled: bool,
/// 线程安全标记
_phantom: PhantomData<*const ()>,
}
impl SceneComponent {
/**
* 创建新的场景组件
*/
pub fn new() -> Self {
Self {
scene_id: None,
update_order: 0,
enabled: true,
_phantom: PhantomData,
}
}
/**
* 创建带有指定更新顺序的场景组件
*/
pub fn with_update_order(update_order: i32) -> Self {
Self {
scene_id: None,
update_order,
enabled: true,
_phantom: PhantomData,
}
}
/**
* 获取是否启用
*/
pub fn is_enabled(&self) -> bool {
self.enabled
}
/**
* 设置是否启用
*/
pub fn set_enabled(&mut self, enabled: bool) {
if self.enabled != enabled {
self.enabled = enabled;
if self.enabled {
self.on_enabled();
} else {
self.on_disabled();
}
}
}
/**
* 获取更新顺序
*/
pub fn get_update_order(&self) -> i32 {
self.update_order
}
/**
* 设置更新顺序
*/
pub fn set_update_order(&mut self, order: i32) {
self.update_order = order;
}
/**
* 获取所属场景ID
*/
pub fn get_scene_id(&self) -> Option<u32> {
self.scene_id
}
/**
* 设置所属场景ID内部方法由Scene调用
*/
pub fn set_scene_id(&mut self, scene_id: Option<u32>) {
self.scene_id = scene_id;
}
/**
* 当组件启用时调用(虚方法,由子类重写)
*/
pub fn on_enabled(&mut self) {
// 默认实现为空,由子类重写
}
/**
* 当组件禁用时调用(虚方法,由子类重写)
*/
pub fn on_disabled(&mut self) {
// 默认实现为空,由子类重写
}
/**
* 当组件从场景中移除时调用(虚方法,由子类重写)
*/
pub fn on_removed_from_scene(&mut self) {
// 默认实现为空,由子类重写
self.scene_id = None;
}
/**
* 每帧更新(虚方法,由子类重写)
*/
pub fn update(&mut self) {
// 默认实现为空,由子类重写
}
/**
* 比较组件的更新顺序
*/
pub fn compare(&self, other: &SceneComponent) -> std::cmp::Ordering {
self.update_order.cmp(&other.update_order)
}
}
impl Default for SceneComponent {
fn default() -> Self {
Self::new()
}
}
// 显式实现Send和Sync因为PhantomData<*const ()>默认不实现这些traits
unsafe impl Send for SceneComponent {}
unsafe impl Sync for SceneComponent {}
impl IUpdatable for SceneComponent {
fn is_enabled(&self) -> bool {
self.enabled
}
fn get_update_order(&self) -> i32 {
self.update_order
}
fn update(&mut self) {
SceneComponent::update(self);
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
/**
* 可更新对象管理器
* 负责管理和更新实现了IUpdatable接口的对象
*/
pub struct UpdatableManager {
updatables: Vec<Box<dyn IUpdatable>>,
needs_sort: bool,
}
impl UpdatableManager {
/**
* 创建新的可更新对象管理器
*/
pub fn new() -> Self {
Self {
updatables: Vec::new(),
needs_sort: false,
}
}
/**
* 添加可更新对象
*/
pub fn add_updatable(&mut self, updatable: Box<dyn IUpdatable>) {
self.updatables.push(updatable);
self.needs_sort = true;
}
/**
* 移除可更新对象(通过索引)
*/
pub fn remove_updatable(&mut self, index: usize) -> Option<Box<dyn IUpdatable>> {
if index < self.updatables.len() {
Some(self.updatables.remove(index))
} else {
None
}
}
/**
* 获取可更新对象数量
*/
pub fn get_count(&self) -> usize {
self.updatables.len()
}
/**
* 清空所有可更新对象
*/
pub fn clear(&mut self) {
self.updatables.clear();
self.needs_sort = false;
}
/**
* 根据更新顺序排序可更新对象
*/
pub fn sort_by_update_order(&mut self) {
if self.needs_sort {
self.updatables.sort_by(|a, b| IUpdatableComparer::compare(a.as_ref(), b.as_ref()));
self.needs_sort = false;
}
}
/**
* 更新所有启用的可更新对象
*/
pub fn update_all(&mut self) {
// 确保按更新顺序排序
self.sort_by_update_order();
// 更新所有启用的对象
for updatable in &mut self.updatables {
if updatable.is_enabled() {
updatable.update();
}
}
}
/**
* 获取启用的可更新对象数量
*/
pub fn get_enabled_count(&self) -> usize {
self.updatables.iter().filter(|u| u.is_enabled()).count()
}
/**
* 检查是否需要排序
*/
pub fn needs_sorting(&self) -> bool {
self.needs_sort
}
/**
* 强制标记需要排序
*/
pub fn mark_needs_sort(&mut self) {
self.needs_sort = true;
}
/**
* 获取指定索引的可更新对象引用
*/
pub fn get_updatable(&self, index: usize) -> Option<&dyn IUpdatable> {
self.updatables.get(index).map(|u| u.as_ref())
}
/**
* 获取指定索引的可更新对象可变引用
*/
pub fn get_updatable_mut(&mut self, index: usize) -> Option<&mut Box<dyn IUpdatable>> {
self.updatables.get_mut(index)
}
}
impl Default for UpdatableManager {
fn default() -> Self {
Self::new()
}
}
/**
* 场景组件管理器
* 专门用于管理场景组件
*/
pub struct SceneComponentManager {
components: Vec<Box<dyn SceneComponentTrait>>,
needs_sort: bool,
}
/**
* 场景组件trait
* 结合SceneComponent和IUpdatable的功能
*/
pub trait SceneComponentTrait: IUpdatable {
/**
* 获取场景组件的基础数据
*/
fn get_base(&self) -> &SceneComponent;
/**
* 获取场景组件的可变基础数据
*/
fn get_base_mut(&mut self) -> &mut SceneComponent;
/**
* 设置所属场景ID
*/
fn set_scene_id(&mut self, scene_id: Option<u32>);
/**
* 当组件启用时调用
*/
fn on_enabled(&mut self);
/**
* 当组件禁用时调用
*/
fn on_disabled(&mut self);
/**
* 当组件从场景中移除时调用
*/
fn on_removed_from_scene(&mut self);
}
impl SceneComponentManager {
/**
* 创建新的场景组件管理器
*/
pub fn new() -> Self {
Self {
components: Vec::new(),
needs_sort: false,
}
}
/**
* 添加场景组件
*/
pub fn add_component(&mut self, component: Box<dyn SceneComponentTrait>) {
self.components.push(component);
self.needs_sort = true;
}
/**
* 移除场景组件
*/
pub fn remove_component(&mut self, index: usize) -> Option<Box<dyn SceneComponentTrait>> {
if index < self.components.len() {
let mut component = self.components.remove(index);
component.on_removed_from_scene();
Some(component)
} else {
None
}
}
/**
* 获取组件数量
*/
pub fn get_count(&self) -> usize {
self.components.len()
}
/**
* 清空所有组件
*/
pub fn clear(&mut self) {
for mut component in self.components.drain(..) {
component.on_removed_from_scene();
}
self.needs_sort = false;
}
/**
* 根据更新顺序排序组件
*/
pub fn sort_by_update_order(&mut self) {
if self.needs_sort {
self.components.sort_by(|a, b| a.get_update_order().cmp(&b.get_update_order()));
self.needs_sort = false;
}
}
/**
* 更新所有启用的组件
*/
pub fn update_all(&mut self) {
// 确保按更新顺序排序
self.sort_by_update_order();
// 更新所有启用的组件
for component in &mut self.components {
if component.is_enabled() {
component.update();
}
}
}
/**
* 设置所有组件的场景ID
*/
pub fn set_scene_id_for_all(&mut self, scene_id: Option<u32>) {
for component in &mut self.components {
component.set_scene_id(scene_id);
}
}
/**
* 获取启用的组件数量
*/
pub fn get_enabled_count(&self) -> usize {
self.components.iter().filter(|c| c.is_enabled()).count()
}
/**
* 获取指定索引的组件引用
*/
pub fn get_component(&self, index: usize) -> Option<&dyn SceneComponentTrait> {
self.components.get(index).map(|c| c.as_ref())
}
/**
* 获取指定索引的组件可变引用
*/
pub fn get_component_mut(&mut self, index: usize) -> Option<&mut Box<dyn SceneComponentTrait>> {
self.components.get_mut(index)
}
}
impl Default for SceneComponentManager {
fn default() -> Self {
Self::new()
}
}
// 为SceneComponent实现SceneComponentTrait
impl SceneComponentTrait for SceneComponent {
fn get_base(&self) -> &SceneComponent {
self
}
fn get_base_mut(&mut self) -> &mut SceneComponent {
self
}
fn set_scene_id(&mut self, scene_id: Option<u32>) {
SceneComponent::set_scene_id(self, scene_id);
}
fn on_enabled(&mut self) {
SceneComponent::on_enabled(self);
}
fn on_disabled(&mut self) {
SceneComponent::on_disabled(self);
}
fn on_removed_from_scene(&mut self) {
SceneComponent::on_removed_from_scene(self);
}
}
#[cfg(test)]
mod tests {
use super::*;
// 测试用的可更新对象
struct TestUpdatable {
enabled: bool,
update_order: i32,
update_count: usize,
}
impl TestUpdatable {
fn new(update_order: i32) -> Self {
Self {
enabled: true,
update_order,
update_count: 0,
}
}
}
impl IUpdatable for TestUpdatable {
fn is_enabled(&self) -> bool {
self.enabled
}
fn get_update_order(&self) -> i32 {
self.update_order
}
fn update(&mut self) {
self.update_count += 1;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[test]
fn test_scene_component_creation() {
let component = SceneComponent::new();
assert!(component.enabled());
assert_eq!(component.get_update_order(), 0);
assert!(component.scene_id.is_none());
}
#[test]
fn test_scene_component_with_update_order() {
let component = SceneComponent::with_update_order(5);
assert!(component.enabled());
assert_eq!(component.get_update_order(), 5);
}
#[test]
fn test_scene_component_enable_disable() {
let mut component = SceneComponent::new();
assert!(component.enabled());
component.set_enabled(false);
assert!(!component.enabled());
component.set_enabled(true);
assert!(component.enabled());
}
#[test]
fn test_scene_component_update_order() {
let mut component = SceneComponent::new();
assert_eq!(component.get_update_order(), 0);
component.set_update_order(10);
assert_eq!(component.get_update_order(), 10);
}
#[test]
fn test_scene_component_comparison() {
let component1 = SceneComponent::with_update_order(5);
let component2 = SceneComponent::with_update_order(10);
let component3 = SceneComponent::with_update_order(5);
assert_eq!(component1.compare(&component2), std::cmp::Ordering::Less);
assert_eq!(component2.compare(&component1), std::cmp::Ordering::Greater);
assert_eq!(component1.compare(&component3), std::cmp::Ordering::Equal);
}
#[test]
fn test_updatable_comparer() {
let updatable1 = TestUpdatable::new(5);
let updatable2 = TestUpdatable::new(10);
let updatable3 = TestUpdatable::new(5);
assert_eq!(IUpdatableComparer::compare(&updatable1, &updatable2), std::cmp::Ordering::Less);
assert_eq!(IUpdatableComparer::compare(&updatable2, &updatable1), std::cmp::Ordering::Greater);
assert_eq!(IUpdatableComparer::compare(&updatable1, &updatable3), std::cmp::Ordering::Equal);
}
#[test]
fn test_updatable_manager_creation() {
let manager = UpdatableManager::new();
assert_eq!(manager.get_count(), 0);
assert_eq!(manager.get_enabled_count(), 0);
assert!(!manager.needs_sorting());
}
#[test]
fn test_updatable_manager_add_remove() {
let mut manager = UpdatableManager::new();
let updatable = TestUpdatable::new(5);
manager.add_updatable(Box::new(updatable));
assert_eq!(manager.get_count(), 1);
assert_eq!(manager.get_enabled_count(), 1);
assert!(manager.needs_sorting());
let removed = manager.remove_updatable(0);
assert!(removed.is_some());
assert_eq!(manager.get_count(), 0);
}
#[test]
fn test_updatable_manager_update_all() {
let mut manager = UpdatableManager::new();
let updatable1 = TestUpdatable::new(10);
let mut updatable2 = TestUpdatable::new(5);
let updatable3 = TestUpdatable::new(15);
// 禁用第二个对象
updatable2.enabled = false;
manager.add_updatable(Box::new(updatable1));
manager.add_updatable(Box::new(updatable2));
manager.add_updatable(Box::new(updatable3));
assert_eq!(manager.get_count(), 3);
assert_eq!(manager.get_enabled_count(), 2); // 只有2个启用
// 更新所有对象
manager.update_all();
// 检查更新次数(通过类型转换)
if let Some(updatable) = manager.get_updatable(0) {
if let Some(test_updatable) = updatable.as_any().downcast_ref::<TestUpdatable>() {
// 由于排序update_order=5的应该是第一个
assert_eq!(test_updatable.update_order, 5);
}
}
}
#[test]
fn test_updatable_manager_sorting() {
let mut manager = UpdatableManager::new();
manager.add_updatable(Box::new(TestUpdatable::new(10)));
manager.add_updatable(Box::new(TestUpdatable::new(5)));
manager.add_updatable(Box::new(TestUpdatable::new(15)));
assert!(manager.needs_sorting());
manager.sort_by_update_order();
assert!(!manager.needs_sorting());
// 检查排序结果
assert_eq!(manager.get_updatable(0).unwrap().get_update_order(), 5);
assert_eq!(manager.get_updatable(1).unwrap().get_update_order(), 10);
assert_eq!(manager.get_updatable(2).unwrap().get_update_order(), 15);
}
#[test]
fn test_updatable_manager_clear() {
let mut manager = UpdatableManager::new();
manager.add_updatable(Box::new(TestUpdatable::new(5)));
manager.add_updatable(Box::new(TestUpdatable::new(10)));
assert_eq!(manager.get_count(), 2);
manager.clear();
assert_eq!(manager.get_count(), 0);
assert_eq!(manager.get_enabled_count(), 0);
assert!(!manager.needs_sorting());
}
#[test]
fn test_scene_component_manager_creation() {
let manager = SceneComponentManager::new();
assert_eq!(manager.get_count(), 0);
assert_eq!(manager.get_enabled_count(), 0);
}
#[test]
fn test_scene_component_manager_add_remove() {
let mut manager = SceneComponentManager::new();
let component = SceneComponent::new();
manager.add_component(Box::new(component));
assert_eq!(manager.get_count(), 1);
assert_eq!(manager.get_enabled_count(), 1);
let removed = manager.remove_component(0);
assert!(removed.is_some());
assert_eq!(manager.get_count(), 0);
}
#[test]
fn test_scene_component_manager_update_all() {
let mut manager = SceneComponentManager::new();
let component1 = SceneComponent::with_update_order(10);
let mut component2 = SceneComponent::with_update_order(5);
let component3 = SceneComponent::with_update_order(15);
// 禁用第二个组件
component2.set_enabled(false);
manager.add_component(Box::new(component1));
manager.add_component(Box::new(component2));
manager.add_component(Box::new(component3));
assert_eq!(manager.get_count(), 3);
assert_eq!(manager.get_enabled_count(), 2); // 只有2个启用
// 更新所有组件
manager.update_all();
// 检查排序结果
assert_eq!(manager.get_component(0).unwrap().get_update_order(), 5);
assert_eq!(manager.get_component(1).unwrap().get_update_order(), 10);
assert_eq!(manager.get_component(2).unwrap().get_update_order(), 15);
}
#[test]
fn test_scene_component_manager_clear() {
let mut manager = SceneComponentManager::new();
manager.add_component(Box::new(SceneComponent::new()));
manager.add_component(Box::new(SceneComponent::new()));
assert_eq!(manager.get_count(), 2);
manager.clear();
assert_eq!(manager.get_count(), 0);
assert_eq!(manager.get_enabled_count(), 0);
}
#[test]
fn test_scene_component_as_updatable() {
let mut component = SceneComponent::with_update_order(5);
assert!(component.enabled());
assert_eq!(component.get_update_order(), 5);
component.update();
component.set_enabled(false);
assert!(!component.enabled());
}
#[test]
fn test_scene_component_trait_implementation() {
let mut component = SceneComponent::with_update_order(10);
// 测试SceneComponentTrait方法
assert_eq!(component.get_base().get_update_order(), 10);
component.get_base_mut().set_update_order(20);
assert_eq!(component.get_update_order(), 20);
component.set_scene_id(None);
assert!(component.get_base().scene_id.is_none());
}
}

View File

@@ -0,0 +1,110 @@
use wasm_bindgen::prelude::*;
use crate::core::component::{Component, BaseComponent};
/**
* Component WASM绑定包装器
* 提供组件管理功能只暴露用户需要的API
*/
#[wasm_bindgen]
pub struct ComponentWrapper {
inner: BaseComponent,
}
#[wasm_bindgen]
impl ComponentWrapper {
#[wasm_bindgen(constructor)]
pub fn new(id: u32) -> Self {
let mut component = BaseComponent::new();
component.set_id(id);
Self {
inner: component,
}
}
#[wasm_bindgen(getter)]
pub fn id(&self) -> u32 {
self.inner.id()
}
#[wasm_bindgen(setter)]
pub fn set_id(&mut self, id: u32) {
self.inner.set_id(id);
}
#[wasm_bindgen(getter)]
pub fn enabled(&self) -> bool {
self.inner.enabled()
}
#[wasm_bindgen(setter)]
pub fn set_enabled(&mut self, enabled: bool) {
self.inner.set_enabled(enabled);
}
/**
* 更新组件
*/
pub fn update(&mut self) {
self.inner.update();
}
/**
* 获取组件调试信息
*/
pub fn get_debug_info(&self) -> String {
format!(
"{{\"id\":{},\"enabled\":{},\"type\":\"Component\"}}",
self.inner.id(),
self.inner.enabled()
)
}
/**
* 获取组件名称
*/
pub fn get_name(&self) -> String {
"Component".to_string()
}
/**
* 检查组件是否已销毁
*/
pub fn is_destroyed(&self) -> bool {
false // BaseComponent不支持销毁状态暂时返回false
}
}
/**
* ComponentRegistry WASM绑定包装器
* 提供组件注册和类型管理功能
*/
#[wasm_bindgen]
pub struct ComponentRegistryWrapper {
// 暂时为空因为ComponentRegistry主要是静态方法
_placeholder: u8,
}
#[wasm_bindgen]
impl ComponentRegistryWrapper {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self {
_placeholder: 0,
}
}
/**
* 获取已注册的组件数量
*/
pub fn get_component_count(&self) -> usize {
// TODO: 从实际的ComponentRegistry获取
0
}
/**
* 获取组件类型信息JSON字符串
*/
pub fn get_component_types_info(&self) -> String {
"[]".to_string() // TODO: 返回实际的组件类型信息
}
}

View File

@@ -0,0 +1,113 @@
use wasm_bindgen::prelude::*;
use js_sys::Uint32Array;
use crate::core::entity_manager::EntityManager;
/**
* EntityManager WASM绑定包装器
* 提供实体管理功能只暴露用户需要的API
*/
#[wasm_bindgen]
pub struct EntityManagerWrapper {
inner: EntityManager,
}
#[wasm_bindgen]
impl EntityManagerWrapper {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self {
inner: EntityManager::new(),
}
}
/**
* 创建新实体
*/
pub fn create_entity(&mut self, name: Option<String>) -> u32 {
let entity_name = name.unwrap_or_else(|| "Entity".to_string());
self.inner.create_entity(Some(entity_name))
}
/**
* 批量创建实体
*/
pub fn create_entities_batch(&mut self, count: u32, name_prefix: Option<String>) -> Uint32Array {
let prefix = name_prefix.unwrap_or_else(|| "Entity".to_string());
let entities = self.inner.create_entities_batch(count, Some(prefix));
Uint32Array::from(&entities[..])
}
/**
* 销毁实体
*/
pub fn destroy_entity(&mut self, entity_id: u32) -> bool {
self.inner.destroy_entity(entity_id)
}
/**
* 获取所有实体ID
*/
pub fn get_all_entity_ids(&self) -> Uint32Array {
let ids = self.inner.get_all_entity_ids();
Uint32Array::from(&ids[..])
}
/**
* 根据名称获取实体
*/
pub fn get_entity_by_name(&self, name: &str) -> Option<u32> {
self.inner.get_entity_by_name(name)
}
/**
* 根据标签获取实体列表
*/
pub fn get_entities_by_tag(&self, tag: u32) -> Uint32Array {
let entities = self.inner.get_entities_by_tag(tag);
Uint32Array::from(&entities[..])
}
/**
* 获取实体总数
*/
pub fn entity_count(&self) -> usize {
self.inner.entity_count()
}
/**
* 获取激活状态的实体数量
*/
pub fn active_entity_count(&self) -> usize {
self.inner.active_entity_count()
}
/**
* 清空所有实体
*/
pub fn clear(&mut self) {
// EntityManager doesn't have clear method, would need implementation
}
/**
* 获取统计信息JSON字符串
*/
pub fn get_stats(&self) -> String {
// 暂时返回简单的统计信息
format!("{{\"entity_count\":{},\"active_entity_count\":{}}}",
self.inner.entity_count(),
self.inner.active_entity_count())
}
}
impl EntityManagerWrapper {
/**
* 内部访问原始EntityManager的方法不暴露给WASM
*/
pub fn inner(&self) -> &EntityManager {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut EntityManager {
&mut self.inner
}
}

View File

@@ -0,0 +1,139 @@
use wasm_bindgen::prelude::*;
use js_sys::Uint32Array;
use crate::core::entity::Entity;
/**
* Entity WASM绑定包装器
* 只暴露用户需要操作的核心API
*/
#[wasm_bindgen]
pub struct EntityWrapper {
inner: Entity,
}
#[wasm_bindgen]
impl EntityWrapper {
#[wasm_bindgen(constructor)]
pub fn new(name: String, id: u32) -> Self {
Self {
inner: {
let mut entity = Entity::new(id);
entity.set_name(name);
entity
},
}
}
#[wasm_bindgen(getter)]
pub fn id(&self) -> u32 {
self.inner.id
}
#[wasm_bindgen(getter)]
pub fn name(&self) -> String {
self.inner.name.clone()
}
#[wasm_bindgen(getter)]
pub fn active(&self) -> bool {
self.inner.active()
}
#[wasm_bindgen(setter)]
pub fn set_active(&mut self, value: bool) {
self.inner.set_active(value);
}
#[wasm_bindgen(getter)]
pub fn enabled(&self) -> bool {
self.inner.enabled()
}
#[wasm_bindgen(setter)]
pub fn set_enabled(&mut self, value: bool) {
self.inner.set_enabled(value);
}
#[wasm_bindgen(getter)]
pub fn tag(&self) -> u32 {
self.inner.tag()
}
#[wasm_bindgen(setter)]
pub fn set_tag(&mut self, value: u32) {
self.inner.set_tag(value);
}
#[wasm_bindgen(getter)]
pub fn update_order(&self) -> i32 {
self.inner.update_order()
}
#[wasm_bindgen(setter)]
pub fn set_update_order(&mut self, value: i32) {
self.inner.set_update_order(value);
}
pub fn is_destroyed(&self) -> bool {
self.inner.is_destroyed()
}
pub fn get_parent_id(&self) -> Option<u32> {
self.inner.get_parent_id()
}
pub fn get_children_ids(&self) -> Uint32Array {
let children = self.inner.get_children_ids();
Uint32Array::from(&children[..])
}
pub fn child_count(&self) -> usize {
self.inner.child_count()
}
pub fn component_count(&self) -> usize {
self.inner.component_count()
}
pub fn get_component_mask(&self) -> u64 {
self.inner.get_component_mask()
}
pub fn destroy(&mut self) {
self.inner.destroy();
}
pub fn update(&mut self) {
self.inner.update();
}
pub fn get_debug_info(&self) -> String {
self.inner.get_debug_info()
}
#[wasm_bindgen(js_name = toString)]
pub fn to_string(&self) -> String {
self.inner.to_string()
}
}
impl EntityWrapper {
/**
* 内部访问原始Entity的方法不暴露给WASM
*/
pub fn inner(&self) -> &Entity {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut Entity {
&mut self.inner
}
pub fn from_entity(entity: Entity) -> Self {
Self { inner: entity }
}
pub fn into_entity(self) -> Entity {
self.inner
}
}

View File

@@ -0,0 +1,11 @@
pub mod entity_wrapper;
pub mod entity_manager_wrapper;
pub mod query_system_wrapper;
pub mod scene_wrapper;
pub mod component_wrapper;
pub use entity_wrapper::EntityWrapper;
pub use entity_manager_wrapper::EntityManagerWrapper;
pub use query_system_wrapper::QuerySystemWrapper;
pub use scene_wrapper::SceneWrapper;
pub use component_wrapper::{ComponentWrapper, ComponentRegistryWrapper};

View File

@@ -0,0 +1,104 @@
use wasm_bindgen::prelude::*;
use js_sys::Uint32Array;
use crate::core::query_system::QuerySystem;
/**
* QuerySystem WASM绑定包装器
* 提供查询功能只暴露用户需要的API
*/
#[wasm_bindgen]
pub struct QuerySystemWrapper {
inner: QuerySystem,
}
#[wasm_bindgen]
impl QuerySystemWrapper {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self {
inner: QuerySystem::new(),
}
}
/**
* 设置实体列表并重建索引
*/
#[allow(unused_variables)]
pub fn set_entities(&mut self, entity_ids: Uint32Array) {
// QuerySystem doesn't have set_entities method, simplified for now
}
/**
* 查询包含所有指定组件的实体
*/
#[allow(unused_variables)]
pub fn query_all(&self, component_mask: &str) -> String {
// Simplified implementation - return empty result
let empty_result = crate::core::query_system::QueryResult {
entities: Vec::new(),
count: 0,
execution_time: 0.0,
from_cache: false,
};
serde_json::to_string(&empty_result).unwrap_or_else(|_| "{}".to_string())
}
/**
* 按标签查询实体
*/
#[allow(unused_variables)]
pub fn query_by_tag(&self, tag: u32) -> String {
// Simplified implementation - return empty result
let empty_result = crate::core::query_system::QueryResult {
entities: Vec::new(),
count: 0,
execution_time: 0.0,
from_cache: false,
};
serde_json::to_string(&empty_result).unwrap_or_else(|_| "{}".to_string())
}
/**
* 按名称查询实体
*/
#[allow(unused_variables)]
pub fn query_by_name(&mut self, name: &str) -> String {
// 这里需要传入EntityManager但WASM包装器暂时无法直接访问
// 返回空结果实际使用时可能需要重新设计API
let empty_result = crate::core::query_system::QueryResult {
entities: Vec::new(),
count: 0,
execution_time: 0.0,
from_cache: false,
};
serde_json::to_string(&empty_result).unwrap_or_else(|_| "{}".to_string())
}
/**
* 获取系统统计信息
*/
pub fn get_stats(&self) -> String {
let stats = self.inner.get_stats();
serde_json::to_string(&stats).unwrap_or_else(|_| "{}".to_string())
}
/**
* 清空所有查询缓存
*/
pub fn clear_cache(&mut self) {
self.inner.clear_cache();
}
}
impl QuerySystemWrapper {
/**
* 内部访问原始QuerySystem的方法不暴露给WASM
*/
pub fn inner(&self) -> &QuerySystem {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut QuerySystem {
&mut self.inner
}
}

View File

@@ -0,0 +1,169 @@
use wasm_bindgen::prelude::*;
use js_sys::Uint32Array;
use crate::core::scene::Scene;
/**
* Scene WASM绑定包装器
* 提供场景管理功能只暴露用户需要的API
*/
#[wasm_bindgen]
pub struct SceneWrapper {
inner: Scene,
}
#[wasm_bindgen]
impl SceneWrapper {
#[wasm_bindgen(constructor)]
pub fn new(name: String) -> Self {
let mut scene = Scene::new();
scene.set_name(name);
Self {
inner: scene,
}
}
// ========== 场景属性 ==========
#[wasm_bindgen(getter)]
pub fn name(&self) -> String {
self.inner.name().to_string()
}
pub fn set_name(&mut self, name: String) {
self.inner.set_name(name);
}
#[wasm_bindgen(getter)]
pub fn active(&self) -> bool {
self.inner.active()
}
#[wasm_bindgen(setter)]
pub fn set_active(&mut self, active: bool) {
self.inner.set_active(active);
}
// ========== 实体管理 ==========
/**
* 创建实体
*/
pub fn create_entity(&mut self, name: Option<String>) -> u32 {
self.inner.create_entity(name)
}
/**
* 批量创建实体
*/
pub fn create_entities_batch(&mut self, count: u32, name_prefix: Option<String>) -> Uint32Array {
let entities = self.inner.create_entities_batch(count, name_prefix);
Uint32Array::from(&entities[..])
}
/**
* 销毁实体
*/
pub fn destroy_entity(&mut self, entity_id: u32) -> bool {
self.inner.destroy_entity(entity_id)
}
/**
* 根据名称获取实体
*/
pub fn get_entity_by_name(&self, name: &str) -> Option<u32> {
self.inner.entity_manager().get_entity_by_name(name)
}
/**
* 根据标签获取实体列表
*/
pub fn get_entities_by_tag(&self, tag: u32) -> Uint32Array {
let entities = self.inner.entity_manager().get_entities_by_tag(tag);
Uint32Array::from(&entities[..])
}
/**
* 获取所有实体ID
*/
pub fn get_all_entity_ids(&self) -> Uint32Array {
let ids = self.inner.entity_manager().get_all_entity_ids();
Uint32Array::from(&ids[..])
}
// ========== 场景生命周期 ==========
/**
* 初始化场景
*/
pub fn initialize(&mut self) {
self.inner.initialize();
}
/**
* 更新场景
*/
pub fn update(&mut self, delta_time: f64) {
self.inner.update(delta_time);
}
/**
* 清空场景
*/
pub fn clear(&mut self) {
self.inner.clear();
}
// ========== 统计信息 ==========
/**
* 获取实体数量
*/
pub fn entity_count(&self) -> usize {
self.inner.entity_count()
}
/**
* 获取激活实体数量
*/
pub fn active_entity_count(&self) -> usize {
self.inner.active_entity_count()
}
/**
* 获取调试信息
*/
pub fn get_debug_info(&self) -> String {
self.inner.get_debug_info()
}
/**
* 获取统计信息JSON字符串
*/
pub fn get_stats(&self) -> String {
let stats = self.inner.get_stats();
let system_count = self.inner.system_manager().system_count();
let enabled_system_count = self.inner.system_manager().enabled_system_count();
format!(
"{{\"total_entities_created\":{},\"total_entities_destroyed\":{},\"total_updates\":{},\"system_count\":{},\"enabled_system_count\":{}}}",
stats.total_entities_created,
stats.total_entities_destroyed,
stats.total_updates,
system_count,
enabled_system_count
)
}
}
impl SceneWrapper {
/**
* 内部访问原始Scene的方法不暴露给WASM
*/
pub fn inner(&self) -> &Scene {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut Scene {
&mut self.inner
}
}