mod key;
mod pipeline;
mod plugin;
use std::sync::Arc;
use bevy::{
prelude::{Commands, Entity},
reflect::{FromReflect, Reflect, TypeUuid},
render::render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef},
};
pub use key::*;
pub use pipeline::*;
pub use plugin::*;
pub trait MaterialUI: AsBindGroup + Send + Sync + Clone + TypeUuid + Sized + 'static {
fn vertex_shader() -> ShaderRef {
ShaderRef::Default
}
fn fragment_shader() -> ShaderRef {
ShaderRef::Default
}
#[allow(unused_variables)]
#[inline]
fn specialize(descriptor: &mut RenderPipelineDescriptor, key: MaterialUIKey<Self>) {}
}
#[derive(Default, Clone, Reflect, FromReflect)]
pub struct MaterialHandle {
uuid: String,
#[reflect(ignore)]
closure: HandleClosure,
}
#[derive(Clone)]
pub struct HandleClosure {
pub(crate) c: Arc<dyn Fn(&mut Commands, Entity)>,
}
unsafe impl Send for HandleClosure {}
unsafe impl Sync for HandleClosure {}
impl Default for HandleClosure {
fn default() -> Self {
Self {
c: Arc::new(|_, _| {}),
}
}
}
impl core::fmt::Debug for MaterialHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MaterialHandle")
.field("uuid", &self.uuid)
.finish()
}
}
impl PartialEq for MaterialHandle {
fn eq(&self, other: &Self) -> bool {
self.uuid == other.uuid
}
}
impl MaterialHandle {
pub fn new<F>(closure: F) -> Self
where
F: Fn(&mut Commands, Entity) + 'static,
{
Self {
uuid: uuid::Uuid::new_v4().to_string(),
closure: HandleClosure {
c: Arc::new(closure),
},
}
}
pub fn run(&self, commands: &mut Commands, id: Entity) {
self.closure.c.as_ref()(commands, id);
}
}