use crate::ecs::graphics::{GraphicsCore, Visual, VisualGraphics, WindowGraphics};
use bevy_ecs::name::Name;
use bevy_ecs::prelude::*;
use tracing::{debug, error, trace};
use windows::UI::Composition::Compositor;
use windows::core::Interface;
use super::format_entity_name;
use super::wuc_resource::WucGraphicsResource;
pub fn insert_visual(world: &mut World, entity: Entity) {
insert_visual_with(world, entity, Visual::default());
}
pub fn insert_visual_with(world: &mut World, entity: Entity, visual: Visual) {
if let Ok(mut entity_mut) = world.get_entity_mut(entity) {
entity_mut.insert(visual);
}
}
fn create_visual_only(entity: Entity, vg: &mut VisualGraphics, compositor: &Compositor) {
let visual_res = compositor
.CreateSpriteVisual()
.and_then(|sprite| sprite.cast::<windows::UI::Composition::Visual>());
match visual_res {
Ok(v) => {
*vg = VisualGraphics::new(v.clone());
debug!(
entity = ?entity,
"Visual created (VisualGraphics initialized)"
);
}
Err(e) => {
error!(error = ?e, "Failed to create visual");
}
}
}
pub fn visual_resource_management_system(
_commands: Commands,
graphics: Res<GraphicsCore>,
wuc_resource: Option<Res<WucGraphicsResource>>,
mut query: Query<
(Entity, &Visual, &mut VisualGraphics, Option<&Name>),
Changed<VisualGraphics>,
>,
frame_count: Res<crate::ecs::world::FrameCount>,
) {
if !graphics.is_valid() {
return;
}
let compositor = match wuc_resource.as_ref().and_then(|r| r.compositor()) {
Some(c) => c,
None => return,
};
for (entity, _visual, mut vg, name) in query.iter_mut() {
if !vg.is_valid() {
let entity_name = format_entity_name(entity, name);
trace!(
frame = frame_count.0,
entity = %entity_name,
"VisualGraphics initialization starting (Changed + !is_valid)"
);
create_visual_only(entity, &mut vg, compositor);
trace!(
frame = frame_count.0,
entity = %entity_name,
"VisualGraphics initialization completed"
);
}
}
}
pub fn window_visual_integration_system(
query: Query<
(Entity, &WindowGraphics, &VisualGraphics, Option<&Name>),
Or<(Changed<WindowGraphics>, Changed<VisualGraphics>)>,
>,
frame_count: Res<crate::ecs::world::FrameCount>,
) {
for (entity, window_graphics, visual_graphics, name) in query.iter() {
if let Some(target) = window_graphics.get_target() {
if let Some(visual) = visual_graphics.visual() {
let entity_name = format_entity_name(entity, name);
trace!(
frame = frame_count.0,
entity = %entity_name,
"SetRoot executing"
);
let _ = target.SetRoot(visual);
}
}
}
}