bevy_yoleck/
editor_window.rs1use bevy::prelude::*;
2use bevy_egui::{egui, EguiContext, PrimaryEguiContext};
3
4use crate::util::EditSpecificResources;
5use crate::YoleckEditorSections;
6
7pub(crate) fn yoleck_editor_window(
8 world: &mut World,
9 mut egui_query: Local<Option<QueryState<&mut EguiContext, With<PrimaryEguiContext>>>>,
10) {
11 let egui_query = egui_query.get_or_insert_with(|| world.query_filtered());
12 let mut borrowed_egui = if let Ok(mut egui_context) = egui_query.single_mut(world) {
13 core::mem::take(egui_context.as_mut())
14 } else {
15 return;
16 };
17 egui::Window::new("Level Editor")
18 .vscroll(true)
19 .show(borrowed_egui.get_mut(), |ui| {
20 world.resource_scope(
21 |world, mut yoleck_editor_sections: Mut<YoleckEditorSections>| {
22 world.resource_scope(|world, mut edit_specific: Mut<EditSpecificResources>| {
23 edit_specific.inject_to_world(world);
24 for section in yoleck_editor_sections.0.iter_mut() {
25 section.0.invoke(world, ui).unwrap();
26 }
27 edit_specific.take_from_world(world);
28 });
29 },
30 );
31 });
32 if let Ok(mut egui_context) = egui_query.single_mut(world) {
33 *egui_context = borrowed_egui;
34 }
35}
36
37#[allow(clippy::type_complexity)]
38enum YoleckEditorSectionInner {
39 Uninitialized(
40 Box<
41 dyn 'static
42 + Send
43 + Sync
44 + FnOnce(
45 &mut World,
46 ) -> Box<
47 dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui) -> Result,
48 >,
49 >,
50 ),
51 Middle,
52 Initialized(Box<dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui) -> Result>),
53}
54
55impl YoleckEditorSectionInner {
56 fn invoke(&mut self, world: &mut World, ui: &mut egui::Ui) -> Result {
57 match self {
58 Self::Uninitialized(_) => {
59 if let Self::Uninitialized(system_constructor) =
60 core::mem::replace(self, Self::Middle)
61 {
62 let mut system = system_constructor(world);
63 system(world, ui)?;
64 *self = Self::Initialized(system);
65 } else {
66 panic!("It was just Uninitialized...");
67 }
68 }
69 Self::Middle => panic!("Cannot start in the middle state when being invoked"),
70 Self::Initialized(system) => {
71 system(world, ui)?;
72 }
73 }
74 Ok(())
75 }
76}
77
78pub struct YoleckEditorSection(YoleckEditorSectionInner);
80
81impl<C, S> From<C> for YoleckEditorSection
82where
83 C: 'static + Send + Sync + FnOnce(&mut World) -> S,
84 S: 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui) -> Result,
85{
86 fn from(system_constructor: C) -> Self {
87 Self(YoleckEditorSectionInner::Uninitialized(Box::new(
88 move |world| Box::new(system_constructor(world)),
89 )))
90 }
91}