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);
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 )
47 -> Box<dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui)>,
48 >,
49 ),
50 Middle,
51 Initialized(Box<dyn 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui)>),
52}
53
54impl YoleckEditorSectionInner {
55 fn invoke(&mut self, world: &mut World, ui: &mut egui::Ui) {
56 match self {
57 Self::Uninitialized(_) => {
58 if let Self::Uninitialized(system_constructor) =
59 core::mem::replace(self, Self::Middle)
60 {
61 let mut system = system_constructor(world);
62 system(world, ui);
63 *self = Self::Initialized(system);
64 } else {
65 panic!("It was just Uninitialized...");
66 }
67 }
68 Self::Middle => panic!("Cannot start in the middle state when being invoked"),
69 Self::Initialized(system) => {
70 system(world, ui);
71 }
72 }
73 }
74}
75
76pub struct YoleckEditorSection(YoleckEditorSectionInner);
78
79impl<C, S> From<C> for YoleckEditorSection
80where
81 C: 'static + Send + Sync + FnOnce(&mut World) -> S,
82 S: 'static + Send + Sync + FnMut(&mut World, &mut egui::Ui),
83{
84 fn from(system_constructor: C) -> Self {
85 Self(YoleckEditorSectionInner::Uninitialized(Box::new(
86 move |world| Box::new(system_constructor(world)),
87 )))
88 }
89}