use super::config::GenerationConfig;
use super::hook_ecs::{DefaultGenerationHookECS, GenerationHookECS};
use super::service::GenerationService;
use super::state_ecs::GenerationStateECS;
use super::system_ecs::GenerationSystemECS;
use issun_macros::Plugin;
use std::sync::Arc;
#[derive(Plugin)]
#[plugin(name = "issun:generation_ecs")]
pub struct GenerationPluginECS {
#[plugin(skip)]
hook: Arc<dyn GenerationHookECS>,
#[plugin(resource)]
config: GenerationConfig,
#[plugin(runtime_state)]
state: GenerationStateECS,
#[plugin(service)]
service: GenerationService,
#[plugin(system)]
system: GenerationSystemECS,
}
impl GenerationPluginECS {
pub fn new() -> Self {
let hook = Arc::new(DefaultGenerationHookECS);
Self {
hook: hook.clone(),
config: GenerationConfig::default(),
state: GenerationStateECS::default(),
service: GenerationService,
system: GenerationSystemECS::new(hook),
}
}
pub fn with_hook<H: GenerationHookECS + 'static>(mut self, hook: H) -> Self {
let hook = Arc::new(hook);
self.hook = hook.clone();
self.system = GenerationSystemECS::new(hook);
self
}
pub fn with_config(mut self, config: GenerationConfig) -> Self {
self.config = config;
self
}
pub fn config(&self) -> &GenerationConfig {
&self.config
}
pub fn state(&self) -> &GenerationStateECS {
&self.state
}
pub fn state_mut(&mut self) -> &mut GenerationStateECS {
&mut self.state
}
pub fn system(&self) -> &GenerationSystemECS {
&self.system
}
pub fn system_mut(&mut self) -> &mut GenerationSystemECS {
&mut self.system
}
}
impl Default for GenerationPluginECS {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::super::types::*;
use super::*;
#[test]
fn test_plugin_creation() {
let plugin = GenerationPluginECS::new();
assert_eq!(plugin.config().global_generation_multiplier, 1.0);
assert_eq!(plugin.state().entity_count(), 0);
}
#[test]
fn test_plugin_with_config() {
let config = GenerationConfig {
global_generation_multiplier: 2.0,
auto_remove_on_complete: true,
max_generation_events: 500,
..Default::default()
};
let plugin = GenerationPluginECS::new().with_config(config);
assert_eq!(plugin.config().global_generation_multiplier, 2.0);
assert!(plugin.config().auto_remove_on_complete);
assert_eq!(plugin.config().max_generation_events, 500);
}
#[tokio::test]
async fn test_plugin_basic_workflow() {
let hook = Arc::new(DefaultGenerationHookECS);
let mut system = GenerationSystemECS::new(hook);
let mut state = GenerationStateECS::new();
let config = GenerationConfig::default();
let entity1 = state.spawn_entity(
Generation::new(100.0, 1.0, GenerationType::Organic),
GenerationEnvironment::default(),
);
let entity2 = state.spawn_entity(
Generation::new(100.0, 2.0, GenerationType::Production),
GenerationEnvironment::default(),
);
assert_eq!(state.entity_count(), 2);
system.update_generation(&mut state, &config, 1.0).await;
let gen1 = state.world.get::<&Generation>(entity1).unwrap();
assert!(gen1.current > 0.0);
let gen2 = state.world.get::<&Generation>(entity2).unwrap();
assert!(gen2.current > 0.0);
assert!(gen2.current > gen1.current);
let metrics = state.metrics();
assert_eq!(metrics.entities_processed, 2);
}
#[tokio::test]
async fn test_plugin_reduce() {
let hook = Arc::new(DefaultGenerationHookECS);
let mut system = GenerationSystemECS::new(hook);
let mut state = GenerationStateECS::new();
let entity = state.spawn_entity(
Generation {
current: 50.0,
max: 100.0,
generation_rate: 1.0,
generation_type: GenerationType::Construction,
status: GenerationStatus::Generating,
paused: false,
},
GenerationEnvironment::default(),
);
let reduced = system
.reduce_entity(entity, 20.0, &mut state)
.await
.unwrap();
assert_eq!(reduced, 20.0);
let generation = state.world.get::<&Generation>(entity).unwrap();
assert_eq!(generation.current, 30.0);
assert_eq!(generation.status, GenerationStatus::Generating);
}
#[tokio::test]
async fn test_plugin_pause_resume() {
let hook = Arc::new(DefaultGenerationHookECS);
let mut system = GenerationSystemECS::new(hook);
let mut state = GenerationStateECS::new();
let entity = state.spawn_entity(
Generation::new(100.0, 1.0, GenerationType::Recovery),
GenerationEnvironment::default(),
);
system.pause_entity(entity, &mut state).await.unwrap();
{
let generation = state.world.get::<&Generation>(entity).unwrap();
assert!(generation.paused);
}
system.resume_entity(entity, &mut state).await.unwrap();
{
let generation = state.world.get::<&Generation>(entity).unwrap();
assert!(!generation.paused);
}
}
}