use crate::prelude::WebviewMaterial;
#[cfg(not(target_os = "macos"))]
use crate::prelude::{WebviewSurface, update_webview_image};
#[cfg(not(target_os = "macos"))]
use bevy::asset::AssetEventSystems;
use bevy::asset::{AssetPath, embedded_asset, embedded_path};
use bevy::pbr::{ExtendedMaterial, MaterialExtension};
use bevy::prelude::*;
use bevy::shader::ShaderRef;
#[cfg(not(target_os = "macos"))]
use bevy_cef_core::prelude::*;
pub(super) struct WebviewExtendStandardMaterialPlugin;
impl Plugin for WebviewExtendStandardMaterialPlugin {
fn build(&self, app: &mut App) {
embedded_asset!(app, "webview_extend_standard_material.wesl");
app.add_plugins(MaterialPlugin::<WebviewExtendStandardMaterial>::default());
#[cfg(not(target_os = "macos"))]
app.add_systems(
PostUpdate,
render_standard_materials.before(AssetEventSystems),
);
}
}
impl MaterialExtension for WebviewMaterial {
fn fragment_shader() -> ShaderRef {
ShaderRef::Path(
AssetPath::from_path_buf(embedded_path!("webview_extend_standard_material.wesl"))
.with_source("embedded"),
)
}
}
pub type WebviewExtendStandardMaterial = ExtendedMaterial<StandardMaterial, WebviewMaterial>;
#[cfg(not(target_os = "macos"))]
fn render_standard_materials(
mut commands: Commands,
mut er: MessageReader<RenderTextureMessage>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
webviews: Query<&MeshMaterial3d<WebviewExtendStandardMaterial>>,
) {
for texture in er.read() {
if let Ok(handle) = webviews.get(texture.webview)
&& let Some(mut material) = materials.get_mut(handle.id())
&& let Some(image) = {
let handle = material
.extension
.surface
.get_or_insert_with(|| images.add(Image::default()));
commands
.entity(texture.webview)
.insert(WebviewSurface(handle.clone()));
images.get_mut(handle.id())
}
{
update_webview_image(texture, image);
}
}
}
#[cfg(target_os = "macos")]
impl crate::webview::gpu_surface::WebviewSurfaceSlot for WebviewExtendStandardMaterial {
fn webview_surface_slot(&self) -> &Option<Handle<Image>> {
&self.extension.surface
}
fn webview_surface_slot_mut(&mut self) -> &mut Option<Handle<Image>> {
&mut self.extension.surface
}
}
#[cfg(all(test, target_os = "macos"))]
mod tests {
use super::*;
use crate::prelude::WebviewMaterial;
use crate::webview::gpu_surface::WebviewSurfaceSlot;
#[test]
fn slot_points_at_extension_surface() {
let mut m = WebviewExtendStandardMaterial {
base: StandardMaterial::default(),
extension: WebviewMaterial::default(),
};
assert!(m.webview_surface_slot().is_none());
*m.webview_surface_slot_mut() = Some(Handle::<Image>::default());
assert!(m.extension.surface.is_some());
}
}