use crate::context::Context;
use async_trait::async_trait;
#[async_trait]
pub trait Entity: Send + Sync {
fn id(&self) -> &str;
async fn update(&mut self, ctx: &mut Context);
async fn on_spawn(&mut self, _ctx: &mut Context) {}
async fn on_destroy(&mut self, _ctx: &mut Context) {}
fn is_dead(&self) -> bool {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Entity; use async_trait::async_trait;
struct TestEntity {
id: String,
update_count: usize,
}
#[async_trait]
impl Entity for TestEntity {
fn id(&self) -> &str {
&self.id
}
async fn update(&mut self, _ctx: &mut Context) {
self.update_count += 1;
}
fn is_dead(&self) -> bool {
self.update_count > 10
}
}
#[tokio::test]
async fn test_entity_creation() {
let entity = TestEntity {
id: "test_entity".to_string(),
update_count: 0,
};
assert_eq!(entity.id(), "test_entity");
assert!(!entity.is_dead());
}
#[tokio::test]
async fn test_entity_update() {
let mut entity = TestEntity {
id: "test_entity".to_string(),
update_count: 0,
};
let mut ctx = Context::new();
entity.update(&mut ctx).await;
assert_eq!(entity.update_count, 1);
for _ in 0..10 {
entity.update(&mut ctx).await;
}
assert!(entity.is_dead());
}
#[derive(Entity)]
struct DerivedPlayer {
#[entity(id)]
name: String,
hp: i32,
}
#[tokio::test]
async fn test_derived_entity() {
let player = DerivedPlayer {
name: "Alice".to_string(),
hp: 100,
};
assert_eq!(player.id(), "Alice");
}
#[tokio::test]
async fn test_derived_entity_update() {
let mut player = DerivedPlayer {
name: "Bob".to_string(),
hp: 100,
};
let mut ctx = Context::new();
player.update(&mut ctx).await;
assert_eq!(player.hp, 100); }
}