1mod priority;
2
3use core::mem;
4
5pub use self::priority::Priority;
6use crate::{
7 bindings::{cc_string, Gui_Add, Gui_Remove, InputDevice, Screen, ScreenVTABLE},
8 std_types::{c_char, c_int, c_void, Box},
9};
10
11pub struct OwnedScreen {
12 pub screen: Box<Screen>,
13 vtable: Box<ScreenVTABLE>,
14 added: bool,
15}
16
17impl OwnedScreen {
18 pub fn new() -> Self {
19 let mut vtable = Box::new(ScreenVTABLE {
20 Init: Some(Init),
21 Update: Some(Update),
22 Free: Some(Free),
23 Render: Some(Render),
24 BuildMesh: Some(BuildMesh),
25 HandlesInputDown: Some(HandlesInputDown),
26 OnInputUp: Some(OnInputUp),
27 HandlesKeyPress: Some(HandlesKeyPress),
28 HandlesTextChanged: Some(HandlesTextChanged),
29 HandlesPointerDown: Some(HandlesPointerDown),
30 OnPointerUp: Some(OnPointerUp),
31 HandlesPointerMove: Some(HandlesPointerMove),
32 HandlesMouseScroll: Some(HandlesMouseScroll),
33 Layout: Some(Layout),
34 ContextLost: Some(ContextLost),
35 ContextRecreated: Some(ContextRecreated),
36 HandlesPadAxis: Some(HandlesPadAxis),
37 });
38
39 let screen = Box::new(unsafe {
40 let mut screen: Screen = mem::zeroed();
41 screen.VTABLE = vtable.as_mut();
42 screen
43 });
44
45 Self {
46 screen,
47 vtable,
48 added: false,
49 }
50 }
51
52 pub fn add<T: Into<Priority>>(&mut self, priority: T) {
53 if self.added {
54 return;
55 }
56 unsafe {
57 Gui_Add(self.screen.as_mut(), priority.into().to_u8() as _);
59 }
60 self.added = true;
61 }
62
63 pub fn remove(&mut self) {
64 if self.added {
65 unsafe {
66 Gui_Remove(self.screen.as_mut());
67 }
68 self.added = false;
69 }
70 }
71
72 pub fn on_init(&mut self, f: unsafe extern "C" fn(elem: *mut c_void)) -> &mut Self {
74 self.vtable.as_mut().Init = Some(f);
75 self
76 }
77
78 pub fn on_update(
80 &mut self,
81 f: unsafe extern "C" fn(elem: *mut c_void, delta: f32),
82 ) -> &mut Self {
83 self.vtable.as_mut().Update = Some(f);
84 self
85 }
86
87 pub fn on_free(&mut self, f: unsafe extern "C" fn(elem: *mut c_void)) -> &mut Self {
89 self.vtable.as_mut().Free = Some(f);
90 self
91 }
92
93 pub fn on_render(
95 &mut self,
96 f: unsafe extern "C" fn(elem: *mut c_void, delta: f32),
97 ) -> &mut Self {
98 self.vtable.as_mut().Render = Some(f);
99 self
100 }
101
102 pub fn on_build_mesh(&mut self, f: unsafe extern "C" fn(elem: *mut c_void)) -> &mut Self {
104 self.vtable.as_mut().BuildMesh = Some(f);
105 self
106 }
107
108 pub fn on_handles_input_down(
110 &mut self,
111 f: unsafe extern "C" fn(elem: *mut c_void, key: c_int, device: *mut InputDevice) -> c_int,
112 ) -> &mut Self {
113 self.vtable.as_mut().HandlesInputDown = Some(f);
114 self
115 }
116
117 pub fn on_on_input_up(
119 &mut self,
120 f: unsafe extern "C" fn(elem: *mut c_void, key: c_int, device: *mut InputDevice),
121 ) -> &mut Self {
122 self.vtable.as_mut().OnInputUp = Some(f);
123 self
124 }
125
126 pub fn on_handles_key_press(
128 &mut self,
129 f: unsafe extern "C" fn(elem: *mut c_void, keyChar: c_char) -> c_int,
130 ) -> &mut Self {
131 self.vtable.as_mut().HandlesKeyPress = Some(f);
132 self
133 }
134
135 pub fn on_handles_text_changed(
138 &mut self,
139 f: unsafe extern "C" fn(elem: *mut c_void, str: *const cc_string) -> c_int,
140 ) -> &mut Self {
141 self.vtable.as_mut().HandlesTextChanged = Some(f);
142 self
143 }
144
145 pub fn on_handles_pointer_down(
147 &mut self,
148 f: unsafe extern "C" fn(elem: *mut c_void, id: c_int, x: c_int, y: c_int) -> c_int,
149 ) -> &mut Self {
150 self.vtable.as_mut().HandlesPointerDown = Some(f);
151 self
152 }
153
154 pub fn on_on_pointer_up(
156 &mut self,
157 f: unsafe extern "C" fn(elem: *mut c_void, id: c_int, x: c_int, y: c_int),
158 ) -> &mut Self {
159 self.vtable.as_mut().OnPointerUp = Some(f);
160 self
161 }
162
163 pub fn on_handles_pointer_move(
165 &mut self,
166 f: unsafe extern "C" fn(elem: *mut c_void, id: c_int, x: c_int, y: c_int) -> c_int,
167 ) -> &mut Self {
168 self.vtable.as_mut().HandlesPointerMove = Some(f);
169 self
170 }
171
172 pub fn on_handles_mouse_scroll(
174 &mut self,
175 f: unsafe extern "C" fn(elem: *mut c_void, delta: f32) -> c_int,
176 ) -> &mut Self {
177 self.vtable.as_mut().HandlesMouseScroll = Some(f);
178 self
179 }
180
181 pub fn on_layout(&mut self, f: unsafe extern "C" fn(elem: *mut c_void)) -> &mut Self {
183 self.vtable.as_mut().Layout = Some(f);
184 self
185 }
186
187 pub fn on_context_lost(&mut self, f: unsafe extern "C" fn(elem: *mut c_void)) -> &mut Self {
189 self.vtable.as_mut().ContextLost = Some(f);
190 self
191 }
192
193 pub fn on_context_recreated(
195 &mut self,
196 f: unsafe extern "C" fn(elem: *mut c_void),
197 ) -> &mut Self {
198 self.vtable.as_mut().ContextRecreated = Some(f);
199 self
200 }
201
202 pub fn on_handles_pad_axis(
204 &mut self,
205 f: unsafe extern "C" fn(elem: *mut c_void, axis: c_int, x: f32, y: f32) -> c_int,
206 ) -> &mut Self {
207 self.vtable.as_mut().HandlesPadAxis = Some(f);
208 self
209 }
210}
211
212impl Default for OwnedScreen {
213 fn default() -> Self {
214 Self::new()
215 }
216}
217
218impl Drop for OwnedScreen {
219 fn drop(&mut self) {
220 #[cfg(not(test))]
221 self.remove();
222 }
223}
224
225unsafe extern "C" fn Init(_elem: *mut c_void) {}
227unsafe extern "C" fn Update(_elem: *mut c_void, _delta: f32) {}
228unsafe extern "C" fn Free(_elem: *mut c_void) {}
229unsafe extern "C" fn Render(_elem: *mut c_void, _delta: f32) {}
230unsafe extern "C" fn BuildMesh(_elem: *mut c_void) {}
231unsafe extern "C" fn HandlesInputDown(
232 _elem: *mut c_void,
233 _key: c_int,
234 _device: *mut InputDevice,
235) -> c_int {
236 0
237}
238unsafe extern "C" fn OnInputUp(_elem: *mut c_void, _key: c_int, _device: *mut InputDevice) {}
239unsafe extern "C" fn HandlesKeyPress(_elem: *mut c_void, _keyChar: c_char) -> c_int {
240 0
241}
242unsafe extern "C" fn HandlesTextChanged(_elem: *mut c_void, _str: *const cc_string) -> c_int {
243 0
244}
245unsafe extern "C" fn HandlesPointerDown(
246 _elem: *mut c_void,
247 _id: c_int,
248 _x: c_int,
249 _y: c_int,
250) -> c_int {
251 0
252}
253unsafe extern "C" fn OnPointerUp(_elem: *mut c_void, _id: c_int, _x: c_int, _y: c_int) {}
254unsafe extern "C" fn HandlesPointerMove(
255 _elem: *mut c_void,
256 _id: c_int,
257 _x: c_int,
258 _y: c_int,
259) -> c_int {
260 0
261}
262unsafe extern "C" fn HandlesMouseScroll(_elem: *mut c_void, _delta: f32) -> c_int {
263 0
264}
265unsafe extern "C" fn Layout(_elem: *mut c_void) {}
266unsafe extern "C" fn ContextLost(_elem: *mut c_void) {}
267unsafe extern "C" fn ContextRecreated(_elem: *mut c_void) {}
268unsafe extern "C" fn HandlesPadAxis(_elem: *mut c_void, _axis: c_int, _x: f32, _y: f32) -> c_int {
269 0
270}
271
272#[test]
273fn test_screen() {
274 extern "C" fn init(_elem: *mut c_void) {
275 }
277
278 let _screen = OwnedScreen::new().on_init(init);
279 let mut screen = OwnedScreen::new();
280 screen.on_init(init);
281}