1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use std::sync::{Mutex, RwLock};
pub use egui::*;
use once_cell::sync::OnceCell;
use super::{FrameworkError, FrameworkGlobal};
mod hook;
unsafe impl Sync for OverlayComponent {}
pub struct OverlayComponent {
renderer: Box<dyn FnMut(&Context) + Send>,
}
struct OverlayState {
hidden: bool,
about: bool,
}
pub struct Overlay {
panels: RwLock<Vec<OverlayComponent>>,
state: Mutex<OverlayState>,
}
impl FrameworkGlobal for Overlay {
fn cell() -> &'static OnceCell<Self> {
static INSTANCE: OnceCell<Overlay> = OnceCell::new();
&INSTANCE
}
fn create() -> Result<Self, FrameworkError> {
hook::install_overlay_hooks()?;
Ok(Overlay {
panels: RwLock::new(vec![]),
state: Mutex::new(OverlayState {
hidden: true,
about: true,
}),
})
}
}
impl Overlay {
pub fn render(&self, context: &egui::Context) {
let mut state = self.state.lock().unwrap();
if context.input().key_pressed(Key::F2) {
state.hidden = !state.hidden;
}
if context.input().key_pressed(Key::F11) {
state.about = !state.about;
}
if state.about {
context.debug_painter().debug_text(
Pos2::new(10.0, 10.0),
Align2::LEFT_TOP,
Color32::WHITE,
format!("me3 v{}", env!("CARGO_PKG_VERSION")),
);
}
if !state.hidden {
let mut panels = self
.panels
.write()
.expect("panel lock was poisoned by writer");
for panel in &mut *panels {
(panel.renderer)(context);
}
}
}
pub fn register_component<F>(&self, renderer: F)
where
F: FnMut(&Context) + Send + 'static,
{
self.panels
.write()
.expect("panel lock was poisoned by previous writer")
.push(OverlayComponent {
renderer: Box::new(renderer),
});
}
pub fn register_panel<F>(&self, title: &'static str, mut renderer: F)
where
F: FnMut(&mut Ui) + Send + 'static,
{
self.register_component(move |ctx| {
egui::containers::Window::new(title)
.resizable(true)
.collapsible(false)
.default_size([250.0, 150.0])
.title_bar(false)
.show(ctx, |ui| (renderer)(ui));
});
}
}