use bevy::prelude::{Commands, Resource, Sprite};
use crate::bevy::prelude::{Quat, Transform, Vec3};
use crate::engine::{agent::Agent, schedule::Schedule, state::State};
use crate::visualization::{
agent_render::{AgentRender, AgentRenderComponent, SpriteType},
asset_handle_factory::AssetHandleFactoryResource,
simulation_descriptor::SimulationDescriptor,
wrappers::SimulationRenderEntity,
};
pub trait VisualizationState<S: State>: Send + Sync + Resource {
fn on_init(
&self,
commands: &mut Commands,
sprite_render_factory: &mut AssetHandleFactoryResource,
state: &mut S,
schedule: &mut Schedule,
sim: &mut SimulationDescriptor,
);
fn setup_graphics(
&self,
schedule: &mut Schedule,
commands: &mut Commands,
state: &mut S,
mut sprite_render_factory: AssetHandleFactoryResource,
) {
for (agent_impl, _) in schedule.events.iter() {
let agent_render = self.get_agent_render(&agent_impl.agent, state);
match agent_render {
Some(agent_render) => {
let boxed_state = Box::new(state.as_state());
let SpriteType::Emoji(emoji_code) =
agent_render.sprite(&agent_impl.agent, &boxed_state);
let sprite_render = sprite_render_factory.get_emoji_loader(emoji_code);
self.setup_agent_graphics(
&agent_impl.agent,
agent_render,
sprite_render,
commands,
&boxed_state,
);
}
None => {}
}
}
}
fn setup_agent_graphics(
&self,
agent: &Box<dyn Agent>,
agent_render: Box<dyn AgentRender>,
sprite: Sprite,
commands: &mut Commands,
state: &Box<&dyn State>,
) {
let (x, y, z) = agent_render.location(agent, state);
let (scale_x, scale_y) = agent_render.scale(agent, state);
let rotation = agent_render.rotation(agent, state);
let mut transform = Transform::from_translation(Vec3::new(x, y + 0.5, z));
transform.scale.x = scale_x;
transform.scale.y = scale_y;
transform.rotation = Quat::from_rotation_z(rotation);
commands
.spawn((sprite, transform))
.insert(AgentRenderComponent(agent_render))
.insert(SimulationRenderEntity);
}
fn get_agent_render(&self, agent: &Box<dyn Agent>, state: &S) -> Option<Box<dyn AgentRender>>;
fn get_agent(
&self,
agent_render: &dyn AgentRender,
state: &Box<&dyn State>,
) -> Option<Box<dyn Agent>>;
fn before_render(
&mut self,
_state: &mut S,
_schedule: &Schedule,
_commands: &mut Commands,
_sprite_factory: &mut AssetHandleFactoryResource,
) {
}
}