Skip to content

Commit

Permalink
Redesign globals, clean codebase from tl::with everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
not-fl3 committed Jul 25, 2023
1 parent 89aa66d commit f46c5dd
Show file tree
Hide file tree
Showing 18 changed files with 968 additions and 1,261 deletions.
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::env;
fn main() {
let target = env::var("TARGET").unwrap_or_else(|e| panic!("{}", e));

if target.contains("darwin") || target.contains("ios"){
if target.contains("darwin") || target.contains("ios") {
println!("cargo:rustc-link-lib=framework=MetalKit");
}
}
26 changes: 25 additions & 1 deletion examples/instancing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,31 @@ impl EventHandler for Stage {
}

fn main() {
let mut conf = conf::Conf::default();
// std::thread::spawn(|| {
// let mut conf = conf::Conf::default();
// let metal = std::env::args().nth(1).as_deref() == Some("metal");
// conf.platform.apple_gfx_api = if metal {
// conf::AppleGfxApi::Metal
// } else {
// conf::AppleGfxApi::OpenGl
// };

// miniquad::start(conf, move || Box::new(Stage::new()));
// });

//let mut conf = conf::Conf::default();
let mut conf = conf::Conf {
window_title: "Miniquad".to_string(),
window_width: 1024,
window_height: 768,
fullscreen: true,
platform: conf::Platform {
linux_backend: conf::LinuxBackend::WaylandOnly,
..Default::default()
},
..Default::default()
};

let metal = std::env::args().nth(1).as_deref() == Some("metal");
conf.platform.apple_gfx_api = if metal {
conf::AppleGfxApi::Metal
Expand Down
4 changes: 4 additions & 0 deletions examples/window_conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ fn main() {
window_width: 1024,
window_height: 768,
fullscreen: true,
platform: conf::Platform {
linux_backend: conf::LinuxBackend::WaylandOnly,
..Default::default()
},
..Default::default()
},
|| {
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ pub struct MetalContext {
impl MetalContext {
pub fn new() -> MetalContext {
unsafe {
let view = crate::window::apple_view().unwrap();
let view = crate::window::apple_view();
assert!(!view.is_null());
let device: ObjcId = msg_send![view, device];
assert!(!device.is_null());
Expand Down
155 changes: 87 additions & 68 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![doc = include_str!("../README.md")]
#![allow(warnings)]

pub mod conf;
mod event;
Expand Down Expand Up @@ -36,49 +37,65 @@ pub mod date {
}
}

use std::cell::RefCell;
thread_local! {
static NATIVE_DISPLAY: RefCell<Option<fn (&mut dyn FnMut(&mut dyn crate::native::NativeDisplay))>> = RefCell::new(None);
}
pub(crate) fn with_native_display(f: &mut dyn FnMut(&mut dyn crate::native::NativeDisplay)) {
NATIVE_DISPLAY.with(|d| (d.borrow().as_ref().unwrap())(f))
}
use std::sync::{Mutex, OnceLock};

// I wish "with_native_display" could be generic over return value, but function
// pointer to a generic function requires way too much unsafe :(
macro_rules! with_native_display {
($target:ident, $f:expr) => {{
let mut res = Default::default();

with_native_display(&mut |$target| {
res = $f;
});
static NATIVE_DISPLAY: OnceLock<Mutex<native::NativeDisplayData>> = OnceLock::new();

res
}};
fn set_display(display: native::NativeDisplayData) {
NATIVE_DISPLAY.set(Mutex::new(display));
}
fn native_display() -> &'static Mutex<native::NativeDisplayData> {
NATIVE_DISPLAY
.get()
.expect("Backend did not initialized NATIVE_DISPLAY yet.") //|| Mutex::new(Default::default()))
}

/// Window and associated to window rendering context related functions.
/// in macroquad <= 0.3, it was ctx.screen_size(). Now it is window::screen_size()
pub mod window {
use super::*;

/// The same as
/// ```ignore
/// if metal {
/// Box::new(MetalContext::new())
/// } else {
/// Box::new(GlContext::new())
/// };
/// ```
/// but under #[cfg] gate to avoid MetalContext on non-apple platforms
pub fn new_rendering_backend() -> Box<dyn RenderingBackend> {
#[cfg(target_vendor = "apple")]
{
if window::apple_gfx_api() == conf::AppleGfxApi::Metal {
Box::new(MetalContext::new())
} else {
Box::new(GlContext::new())
}
}
#[cfg(not(target_vendor = "apple"))]
Box::new(GlContext::new())
}

/// The current framebuffer size in pixels
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn screen_size() -> (f32, f32) {
with_native_display!(d, d.screen_size())
let d = native_display().lock().unwrap();
(d.screen_width as f32, d.screen_height as f32)
}

/// The dpi scaling factor (window pixels to framebuffer pixels)
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn dpi_scale() -> f32 {
with_native_display!(d, d.dpi_scale())
let d = native_display().lock().unwrap();
d.dpi_scale
}

/// True when high_dpi was requested and actually running in a high-dpi scenario
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn high_dpi() -> bool {
with_native_display!(d, d.high_dpi())
let d = native_display().lock().unwrap();
d.high_dpi
}

/// This function simply quits the application without
Expand All @@ -89,7 +106,13 @@ pub mod window {
/// happen in the order_quit implmentation) and execution might continue for some time after
/// But the window is going to be inevitably closed at some point.
pub fn order_quit() {
with_native_display!(d, d.order_quit())
let mut d = native_display().lock().unwrap();
d.quit_ordered = true;
}

/// Shortcut for `order_quit`. Will add a legacy attribute at some point.
pub fn quit() {
order_quit()
}

/// Calling request_quit() will trigger "quit_requested_event" event , giving
Expand All @@ -98,7 +121,8 @@ pub mod window {
/// If the event handler callback does nothing, the application will be quit as usual.
/// To prevent this, call the function "cancel_quit()"" from inside the event handler.
pub fn request_quit() {
with_native_display!(d, d.request_quit())
let mut d = native_display().lock().unwrap();
d.quit_requested = true;
}

/// Cancels a pending quit request, either initiated
Expand All @@ -107,98 +131,93 @@ pub mod window {
/// function makes sense is from inside the event handler callback when
/// the "quit_requested_event" event has been received
pub fn cancel_quit() {
with_native_display!(d, d.cancel_quit())
let mut d = native_display().lock().unwrap();
d.quit_requested = false;
}

/// Capture mouse cursor to the current window
/// On WASM this will automatically hide cursor
/// On desktop this will bound cursor to windows border
/// NOTICE: on desktop cursor will not be automatically released after window lost focus
/// so set_cursor_grab(false) on window's focus lost is recommended.
/// TODO: implement window focus events
pub fn set_cursor_grab(grab: bool) {
with_native_display!(d, d.set_cursor_grab(grab))
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::SetCursorGrab(grab));
}

/// Show or hide the mouse cursor
pub fn show_mouse(shown: bool) {
with_native_display!(d, d.show_mouse(shown))
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::ShowMouse(shown));
}

/// Set the mouse cursor icon.
pub fn set_mouse_cursor(cursor_icon: CursorIcon) {
with_native_display!(d, d.set_mouse_cursor(cursor_icon))
let mut d = native_display().lock().unwrap();
d.native_requests
.send(native::Request::SetMouseCursor(cursor_icon));
}

/// Set the application's window size.
pub fn set_window_size(new_width: u32, new_height: u32) {
with_native_display!(d, d.set_window_size(new_width, new_height))
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::SetWindowSize {
new_width,
new_height,
});
}

pub fn set_fullscreen(fullscreen: bool) {
with_native_display!(d, d.set_fullscreen(fullscreen))
let mut d = native_display().lock().unwrap();
d.native_requests
.send(native::Request::SetFullscreen(fullscreen));
}

/// Get current OS clipboard value
pub fn clipboard_get() -> Option<String> {
with_native_display!(d, d.clipboard_get())
let mut d = native_display().lock().unwrap();
d.clipboard.get()
}

/// Save value to OS clipboard
pub fn clipboard_set(data: &str) {
with_native_display!(d, d.clipboard_set(data))
let mut d = native_display().lock().unwrap();
d.clipboard.set(data)
}
pub fn dropped_file_count() -> usize {
with_native_display!(d, d.dropped_file_count())
let d = native_display().lock().unwrap();
d.dropped_files.bytes.len()
}
pub fn dropped_file_bytes(index: usize) -> Option<Vec<u8>> {
with_native_display!(d, d.dropped_file_bytes(index))
let d = native_display().lock().unwrap();
d.dropped_files.bytes.get(index).cloned()
}
pub fn dropped_file_path(index: usize) -> Option<std::path::PathBuf> {
with_native_display!(d, d.dropped_file_path(index))
}

/// Shortcut for `order_quit`. Will add a legacy attribute at some point.
pub fn quit() {
with_native_display!(d, d.order_quit())
let d = native_display().lock().unwrap();
d.dropped_files.paths.get(index).cloned()
}

/// Show/hide onscreen keyboard.
/// Only works on Android right now.
pub fn show_keyboard(show: bool) {
with_native_display!(d, d.show_keyboard(show))
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::ShowKeyboard(show));
}

/// The same as
/// ```ignore
/// if metal {
/// Box::new(MetalContext::new())
/// } else {
/// Box::new(GlContext::new())
/// };
/// ```
/// but under #[cfg] gate to avoid MetalContext on non-apple platforms
pub fn new_rendering_backend() -> Box<dyn RenderingBackend> {
#[cfg(target_vendor = "apple")]
{
if with_native_display!(d, d.apple_gfx_api() == conf::AppleGfxApi::Metal) {
Box::new(MetalContext::new())
} else {
Box::new(GlContext::new())
}
}
#[cfg(not(target_vendor = "apple"))]
Box::new(GlContext::new())
#[cfg(target_vendor = "apple")]
pub fn apple_gfx_api() -> crate::conf::AppleGfxApi {
let d = native_display().lock().unwrap();
d.gfx_api
}

#[cfg(target_vendor = "apple")]
pub unsafe fn apple_view() -> Option<crate::native::apple::frameworks::ObjcId> {
with_native_display!(d, d.apple_view())
pub fn apple_view() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
d.view
}

#[cfg(target_os = "ios")]
pub unsafe fn apple_view_ctrl() -> Option<crate::native::apple::frameworks::ObjcId> {
with_native_display!(d, d.apple_view_ctrl())
#[cfg(target_ios = "ios")]
pub fn apple_view_ctrl() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
d.view_ctrl
}
}

Expand Down
Loading

0 comments on commit f46c5dd

Please sign in to comment.