use super::map::{log_map_events, update_loading_maps, update_map_vertex_attributes};
use bevy::{
prelude::*,
render::render_resource::{encase::internal::WriteInto, AsBindGroup, ShaderSize, ShaderType},
sprite::Material2dPlugin,
};
use super::{
map::{DefaultUserData, Map},
shader::SHADER_CODE,
};
pub trait Customization: Sync + Send + 'static + TypePath + Clone
{
const SHADER_HANDLE: Handle<Shader>;
type UserData: AsBindGroup
+ Reflect
+ Clone
+ TypePath
+ ShaderType
+ WriteInto
+ ShaderSize
+ Default;
fn custom_shader_code() -> String;
}
#[derive(Clone, TypePath, Default)]
pub struct NoCustomization;
impl Customization for NoCustomization {
fn custom_shader_code() -> String { r#"
struct UserData {
dummy: u32,
};
fn sample_tile(in: ExtractIn) -> vec4<f32> {
return sample_tile_at(in.tile_index, in.tile_position, in.tile_offset);
}
"#.to_string()
}
const SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(15375856360518374895);
type UserData = DefaultUserData;
}
pub type FastTileMapPlugin = CustomFastTileMapPlugin<NoCustomization>;
#[derive(Default)]
pub struct CustomFastTileMapPlugin<C: Customization = NoCustomization> {
_customization: std::marker::PhantomData<C>,
}
impl<C: Customization> Plugin for CustomFastTileMapPlugin<C> {
fn build(&self, app: &mut App) {
app.add_plugins(Material2dPlugin::<Map<C>>::default());
let mut shaders = app.world_mut().resource_mut::<Assets<Shader>>();
let mut code = SHADER_CODE.to_string();
code = code.replace("#[user_code]", C::custom_shader_code().as_str());
shaders.insert(&C::SHADER_HANDLE, Shader::from_wgsl(code, file!()));
app.add_systems(
Update,
(
(update_loading_maps::<C>, log_map_events::<C>).chain(),
update_map_vertex_attributes::<C>,
),
);
}
}