use crate::engine::{
fields::{dense_object_grid_2d::DenseGrid2D, sparse_object_grid_2d::SparseGrid2D},
location::Int2D,
state::State,
};
use crate::visualization::{
asset_handle_factory::AssetHandleFactoryResource,
wrappers::{ActiveState, SimulationRenderEntity},
};
use crate::bevy::math::Quat;
use bevy::prelude::{Commands, Component, Query, Res, Sprite, Transform};
use std::hash::Hash;
use std::marker::PhantomData;
use std::marker::Sync;
pub trait RenderObjectGrid2D<S: State, O: 'static + Sync + Send + Hash + Copy + Eq + Component> {
fn init_graphics_grid(
sprite_render_factory: &mut AssetHandleFactoryResource,
commands: &mut Commands,
state_wrapper: &S,
) where
Self: 'static + Sized + Sync + Send,
{
let state = &state_wrapper;
let sparse_grid: Option<&SparseGrid2D<O>> = Self::fetch_sparse_grid(state);
let dense_grid: Option<&DenseGrid2D<O>> = Self::fetch_dense_grid(state);
if sparse_grid.is_some() {
for obj in sparse_grid
.expect("error on unwrapping sparse grid")
.obj2loc
.keys()
{
let emoji = Self::fetch_emoji(state, obj);
let sprite = sprite_render_factory.get_emoji_loader(emoji);
let loc = Self::fetch_loc(state, obj).expect("error on fetch_loc");
let rotation = Quat::from_rotation_z(Self::fetch_rotation(state, obj));
let mut transform = Transform::from_xyz(loc.x as f32, loc.y as f32 - 0.5, 0.);
transform.rotation = rotation;
let scale = Self::scale(obj);
transform.scale.x = scale.0;
transform.scale.y = scale.1;
commands
.spawn((sprite, transform))
.insert(Marker::<Self> {
marker: PhantomData,
})
.insert(SimulationRenderEntity)
.insert(obj.clone());
}
} else if dense_grid.is_some() {
for obj in dense_grid
.expect("error on unwrapping dense_grid")
.obj2loc
.keys()
{
let emoji = Self::fetch_emoji(state, obj);
let sprite = sprite_render_factory.get_emoji_loader(emoji);
let loc = Self::fetch_loc(state, obj).expect("error on fetch_lock");
let rotation = Quat::from_rotation_z(Self::fetch_rotation(state, obj));
let mut transform = Transform::from_xyz(loc.x as f32, loc.y as f32 - 0.5, 0.);
transform.rotation = rotation;
let scale = Self::scale(obj);
transform.scale.x = scale.0;
transform.scale.y = scale.1;
commands
.spawn((sprite, transform))
.insert(Marker::<Self> {
marker: PhantomData,
})
.insert(SimulationRenderEntity)
.insert(obj.clone());
}
}
}
fn fetch_sparse_grid(state: &S) -> Option<&SparseGrid2D<O>>;
fn fetch_dense_grid(state: &S) -> Option<&DenseGrid2D<O>>;
fn fetch_emoji(state: &S, obj: &O) -> String;
fn fetch_loc(state: &S, obj: &O) -> Option<Int2D>;
fn fetch_rotation(state: &S, obj: &O) -> f32;
fn scale(obj: &O) -> (f32, f32);
fn render(
mut query: Query<(&Marker<Self>, &O, &mut Transform, &mut Sprite)>,
mut sprite_render_factory: AssetHandleFactoryResource,
state_wrapper: Res<ActiveState<S>>,
) where
Self: 'static + Sized + Sync + Send,
{
let state = &*state_wrapper.0.lock().expect("error on lock");
for (_marker, obj, mut transform, mut sprite) in query.iter_mut() {
let loc = match Self::fetch_loc(state, obj) {
Some(x) => x,
None => {
continue;
}
};
let new_material =
sprite_render_factory.get_material_handle(Self::fetch_emoji(state, obj));
sprite.image = new_material;
transform.translation.x = loc.x as f32;
transform.translation.y = loc.y as f32 + 0.5;
let rotation = Quat::from_rotation_z(Self::fetch_rotation(state, obj));
transform.rotation = rotation;
}
}
}
#[derive(Component)]
pub struct Marker<T> {
marker: PhantomData<T>,
}