Files
esengine/packages/core-rust/src/core/entity.rs

638 lines
17 KiB
Rust
Raw Normal View History

2025-08-18 20:46:47 +08:00
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()
}
}