bevy_yoleck/
editor_window.rs1use bevy::prelude::*;
2use bevy::window::PrimaryWindow;
3use bevy_egui::{egui, EguiContext};
4
5use crate::util::EditSpecificResources;
6use crate::YoleckEditorSections;
7
8pub(crate) fn yoleck_editor_window(
9 world: &mut World,
10 mut egui_query: Local<Option<QueryState<&mut EguiContext, With<PrimaryWindow>>>>,
11) {
12 let egui_query = egui_query.get_or_insert_with(|| world.query_filtered());
13 let mut borrowed_egui = if let Ok(mut egui_context) = egui_query.single_mut(world) {
14 core::mem::take(egui_context.as_mut())
15 } else {
16 return;
17 };
18 egui::Window::new("Level Editor")
19 .vscroll(true)
20 .show(borrowed_egui.get_mut(), |ui| {
21 world.resource_scope(
22 |world, mut yoleck_editor_sections: Mut<YoleckEditorSections>| {
23 world.resource_scope(|world, mut edit_specific: Mut<EditSpecificResources>| {
24 edit_specific.inject_to_world(world);
25 for section in yoleck_editor_sections.0.iter_mut() {
26 section.0.invoke(world, ui);
27 }
28 edit_specific.take_from_world(world);
29 });
30 },
31 );
32 });
33 if let Ok(mut egui_context) = egui_query.single_mut(world) {
34 *egui_context = borrowed_egui;
35 }
36}
37
38#[allow(clippy::type_complexity)]
39enum YoleckEditorSectionInner {
40 Uninitialized(
41 Box<
42 dyn 'static
43 + Send
44 + Sync
45 + FnOnce(
46 &mut World,
47 )
48 -> Box<dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui)>,
49 >,
50 ),
51 Middle,
52 Initialized(Box<dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui)>),
53}
54
55impl YoleckEditorSectionInner {
56 fn invoke(&mut self, world: &mut World, ui: &mut egui::Ui) {
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 }
75}
76
77pub struct YoleckEditorSection(YoleckEditorSectionInner);
79
80impl<C, S> From<C> for YoleckEditorSection
81where
82 C: 'static + Send + Sync + FnOnce(&mut World) -> S,
83 S: 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui),
84{
85 fn from(system_constructor: C) -> Self {
86 Self(YoleckEditorSectionInner::Uninitialized(Box::new(
87 move |world| Box::new(system_constructor(world)),
88 )))
89 }
90}