1
1
#![ doc = include_str ! ( "../README.md" ) ]
2
+ #![ allow( warnings) ]
2
3
3
4
pub mod conf;
4
5
mod event;
@@ -36,49 +37,65 @@ pub mod date {
36
37
}
37
38
}
38
39
39
- use std:: cell:: RefCell ;
40
- thread_local ! {
41
- static NATIVE_DISPLAY : RefCell <Option <fn ( & mut dyn FnMut ( & mut dyn crate :: native:: NativeDisplay ) ) >> = RefCell :: new( None ) ;
42
- }
43
- pub ( crate ) fn with_native_display ( f : & mut dyn FnMut ( & mut dyn crate :: native:: NativeDisplay ) ) {
44
- NATIVE_DISPLAY . with ( |d| ( d. borrow ( ) . as_ref ( ) . unwrap ( ) ) ( f) )
45
- }
40
+ use std:: sync:: { Mutex , OnceLock } ;
46
41
47
- // I wish "with_native_display" could be generic over return value, but function
48
- // pointer to a generic function requires way too much unsafe :(
49
- macro_rules! with_native_display {
50
- ( $target: ident, $f: expr) => { {
51
- let mut res = Default :: default ( ) ;
52
-
53
- with_native_display( & mut |$target| {
54
- res = $f;
55
- } ) ;
42
+ static NATIVE_DISPLAY : OnceLock < Mutex < native:: NativeDisplayData > > = OnceLock :: new ( ) ;
56
43
57
- res
58
- } } ;
44
+ fn set_display ( display : native:: NativeDisplayData ) {
45
+ NATIVE_DISPLAY . set ( Mutex :: new ( display) ) ;
46
+ }
47
+ fn native_display ( ) -> & ' static Mutex < native:: NativeDisplayData > {
48
+ NATIVE_DISPLAY
49
+ . get ( )
50
+ . expect ( "Backend did not initialized NATIVE_DISPLAY yet." ) //|| Mutex::new(Default::default()))
59
51
}
60
52
61
53
/// Window and associated to window rendering context related functions.
62
54
/// in macroquad <= 0.3, it was ctx.screen_size(). Now it is window::screen_size()
63
55
pub mod window {
64
56
use super :: * ;
65
57
58
+ /// The same as
59
+ /// ```ignore
60
+ /// if metal {
61
+ /// Box::new(MetalContext::new())
62
+ /// } else {
63
+ /// Box::new(GlContext::new())
64
+ /// };
65
+ /// ```
66
+ /// but under #[cfg] gate to avoid MetalContext on non-apple platforms
67
+ pub fn new_rendering_backend ( ) -> Box < dyn RenderingBackend > {
68
+ #[ cfg( target_vendor = "apple" ) ]
69
+ {
70
+ if window:: apple_gfx_api ( ) == conf:: AppleGfxApi :: Metal {
71
+ Box :: new ( MetalContext :: new ( ) )
72
+ } else {
73
+ Box :: new ( GlContext :: new ( ) )
74
+ }
75
+ }
76
+ #[ cfg( not( target_vendor = "apple" ) ) ]
77
+ Box :: new ( GlContext :: new ( ) )
78
+ }
79
+
66
80
/// The current framebuffer size in pixels
67
81
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
68
82
pub fn screen_size ( ) -> ( f32 , f32 ) {
69
- with_native_display ! ( d, d. screen_size( ) )
83
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
84
+ ( d. screen_width as f32 , d. screen_height as f32 )
70
85
}
71
86
72
87
/// The dpi scaling factor (window pixels to framebuffer pixels)
73
88
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
74
89
pub fn dpi_scale ( ) -> f32 {
75
- with_native_display ! ( d, d. dpi_scale( ) )
90
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
91
+ d. dpi_scale
76
92
}
77
93
78
94
/// True when high_dpi was requested and actually running in a high-dpi scenario
79
95
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
80
96
pub fn high_dpi ( ) -> bool {
81
- with_native_display ! ( d, d. high_dpi( ) )
97
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
98
+ d. high_dpi
82
99
}
83
100
84
101
/// This function simply quits the application without
@@ -89,7 +106,13 @@ pub mod window {
89
106
/// happen in the order_quit implmentation) and execution might continue for some time after
90
107
/// But the window is going to be inevitably closed at some point.
91
108
pub fn order_quit ( ) {
92
- with_native_display ! ( d, d. order_quit( ) )
109
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
110
+ d. quit_ordered = true ;
111
+ }
112
+
113
+ /// Shortcut for `order_quit`. Will add a legacy attribute at some point.
114
+ pub fn quit ( ) {
115
+ order_quit ( )
93
116
}
94
117
95
118
/// Calling request_quit() will trigger "quit_requested_event" event , giving
@@ -98,7 +121,8 @@ pub mod window {
98
121
/// If the event handler callback does nothing, the application will be quit as usual.
99
122
/// To prevent this, call the function "cancel_quit()"" from inside the event handler.
100
123
pub fn request_quit ( ) {
101
- with_native_display ! ( d, d. request_quit( ) )
124
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
125
+ d. quit_requested = true ;
102
126
}
103
127
104
128
/// Cancels a pending quit request, either initiated
@@ -107,98 +131,93 @@ pub mod window {
107
131
/// function makes sense is from inside the event handler callback when
108
132
/// the "quit_requested_event" event has been received
109
133
pub fn cancel_quit ( ) {
110
- with_native_display ! ( d, d. cancel_quit( ) )
134
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
135
+ d. quit_requested = false ;
111
136
}
112
-
113
137
/// Capture mouse cursor to the current window
114
138
/// On WASM this will automatically hide cursor
115
139
/// On desktop this will bound cursor to windows border
116
140
/// NOTICE: on desktop cursor will not be automatically released after window lost focus
117
141
/// so set_cursor_grab(false) on window's focus lost is recommended.
118
142
/// TODO: implement window focus events
119
143
pub fn set_cursor_grab ( grab : bool ) {
120
- with_native_display ! ( d, d. set_cursor_grab( grab) )
144
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
145
+ d. native_requests . send ( native:: Request :: SetCursorGrab ( grab) ) ;
121
146
}
122
147
123
148
/// Show or hide the mouse cursor
124
149
pub fn show_mouse ( shown : bool ) {
125
- with_native_display ! ( d, d. show_mouse( shown) )
150
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
151
+ d. native_requests . send ( native:: Request :: ShowMouse ( shown) ) ;
126
152
}
127
153
128
154
/// Set the mouse cursor icon.
129
155
pub fn set_mouse_cursor ( cursor_icon : CursorIcon ) {
130
- with_native_display ! ( d, d. set_mouse_cursor( cursor_icon) )
156
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
157
+ d. native_requests
158
+ . send ( native:: Request :: SetMouseCursor ( cursor_icon) ) ;
131
159
}
132
160
133
161
/// Set the application's window size.
134
162
pub fn set_window_size ( new_width : u32 , new_height : u32 ) {
135
- with_native_display ! ( d, d. set_window_size( new_width, new_height) )
163
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
164
+ d. native_requests . send ( native:: Request :: SetWindowSize {
165
+ new_width,
166
+ new_height,
167
+ } ) ;
136
168
}
137
169
138
170
pub fn set_fullscreen ( fullscreen : bool ) {
139
- with_native_display ! ( d, d. set_fullscreen( fullscreen) )
171
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
172
+ d. native_requests
173
+ . send ( native:: Request :: SetFullscreen ( fullscreen) ) ;
140
174
}
141
175
142
176
/// Get current OS clipboard value
143
177
pub fn clipboard_get ( ) -> Option < String > {
144
- with_native_display ! ( d, d. clipboard_get( ) )
178
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
179
+ d. clipboard . get ( )
145
180
}
146
181
147
182
/// Save value to OS clipboard
148
183
pub fn clipboard_set ( data : & str ) {
149
- with_native_display ! ( d, d. clipboard_set( data) )
184
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
185
+ d. clipboard . set ( data)
150
186
}
151
187
pub fn dropped_file_count ( ) -> usize {
152
- with_native_display ! ( d, d. dropped_file_count( ) )
188
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
189
+ d. dropped_files . bytes . len ( )
153
190
}
154
191
pub fn dropped_file_bytes ( index : usize ) -> Option < Vec < u8 > > {
155
- with_native_display ! ( d, d. dropped_file_bytes( index) )
192
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
193
+ d. dropped_files . bytes . get ( index) . cloned ( )
156
194
}
157
195
pub fn dropped_file_path ( index : usize ) -> Option < std:: path:: PathBuf > {
158
- with_native_display ! ( d, d. dropped_file_path( index) )
159
- }
160
-
161
- /// Shortcut for `order_quit`. Will add a legacy attribute at some point.
162
- pub fn quit ( ) {
163
- with_native_display ! ( d, d. order_quit( ) )
196
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
197
+ d. dropped_files . paths . get ( index) . cloned ( )
164
198
}
165
199
166
200
/// Show/hide onscreen keyboard.
167
201
/// Only works on Android right now.
168
202
pub fn show_keyboard ( show : bool ) {
169
- with_native_display ! ( d, d. show_keyboard( show) )
203
+ let mut d = native_display ( ) . lock ( ) . unwrap ( ) ;
204
+ d. native_requests . send ( native:: Request :: ShowKeyboard ( show) ) ;
170
205
}
171
206
172
- /// The same as
173
- /// ```ignore
174
- /// if metal {
175
- /// Box::new(MetalContext::new())
176
- /// } else {
177
- /// Box::new(GlContext::new())
178
- /// };
179
- /// ```
180
- /// but under #[cfg] gate to avoid MetalContext on non-apple platforms
181
- pub fn new_rendering_backend ( ) -> Box < dyn RenderingBackend > {
182
- #[ cfg( target_vendor = "apple" ) ]
183
- {
184
- if with_native_display ! ( d, d. apple_gfx_api( ) == conf:: AppleGfxApi :: Metal ) {
185
- Box :: new ( MetalContext :: new ( ) )
186
- } else {
187
- Box :: new ( GlContext :: new ( ) )
188
- }
189
- }
190
- #[ cfg( not( target_vendor = "apple" ) ) ]
191
- Box :: new ( GlContext :: new ( ) )
207
+ #[ cfg( target_vendor = "apple" ) ]
208
+ pub fn apple_gfx_api ( ) -> crate :: conf:: AppleGfxApi {
209
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
210
+ d. gfx_api
192
211
}
193
-
194
212
#[ cfg( target_vendor = "apple" ) ]
195
- pub unsafe fn apple_view ( ) -> Option < crate :: native:: apple:: frameworks:: ObjcId > {
196
- with_native_display ! ( d, d. apple_view( ) )
213
+ pub fn apple_view ( ) -> crate :: native:: apple:: frameworks:: ObjcId {
214
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
215
+ d. view
197
216
}
198
-
199
- # [ cfg ( target_os = "ios" ) ]
200
- pub unsafe fn apple_view_ctrl ( ) -> Option < crate :: native :: apple :: frameworks :: ObjcId > {
201
- with_native_display ! ( d , d . apple_view_ctrl ( ) )
217
+ # [ cfg ( target_ios = "ios" ) ]
218
+ pub fn apple_view_ctrl ( ) -> crate :: native :: apple :: frameworks :: ObjcId {
219
+ let d = native_display ( ) . lock ( ) . unwrap ( ) ;
220
+ d . view_ctrl
202
221
}
203
222
}
204
223
0 commit comments