Skip to content

Commit

Permalink
Use MainThreadBound instead of StaticMainThreadBound hack
Browse files Browse the repository at this point in the history
MainThreadBound::new and MainThreadMarker::new_unchecked are now
available in `const`.
  • Loading branch information
madsmtm committed Jan 27, 2025
1 parent 45f4e45 commit 8afd509
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 29 deletions.
19 changes: 4 additions & 15 deletions src/platform_impl/apple/appkit/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::sync::atomic::Ordering as AtomicOrdering;
use std::sync::Arc;
use std::time::Instant;

use dispatch2::MainThreadBound;
use objc2::MainThreadMarker;
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSRunningApplication};
use objc2_foundation::NSNotification;
Expand Down Expand Up @@ -46,22 +47,10 @@ pub(super) struct AppState {
// as such should be careful to not add fields that, in turn, strongly reference those.
}

// TODO(madsmtm): Use `MainThreadBound` once that is possible in `static`s.
struct StaticMainThreadBound<T>(T);

impl<T> StaticMainThreadBound<T> {
const fn get(&self, _mtm: MainThreadMarker) -> &T {
&self.0
}
}

unsafe impl<T> Send for StaticMainThreadBound<T> {}
unsafe impl<T> Sync for StaticMainThreadBound<T> {}

// SAFETY: Creating `StaticMainThreadBound` in a `const` context, where there is no concept of the
// SAFETY: Creating `MainThreadBound` in a `const` context, where there is no concept of the
// main thread.
static GLOBAL: StaticMainThreadBound<OnceCell<Rc<AppState>>> =
StaticMainThreadBound(OnceCell::new());
static GLOBAL: MainThreadBound<OnceCell<Rc<AppState>>> =
MainThreadBound::new(OnceCell::new(), unsafe { MainThreadMarker::new_unchecked() });

impl AppState {
pub(super) fn setup_global(
Expand Down
17 changes: 3 additions & 14 deletions src/platform_impl/apple/uikit/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex};
use std::time::Instant;
use std::{mem, ptr};

use dispatch2::MainThreadBound;
use objc2::rc::Retained;
use objc2::MainThreadMarker;
use objc2_core_foundation::{
Expand Down Expand Up @@ -43,22 +44,10 @@ macro_rules! bug_assert {
/// This is stored separately from AppState, since AppState needs to be accessible while the handler
/// is executing.
fn get_handler(mtm: MainThreadMarker) -> &'static EventHandler {
// TODO(madsmtm): Use `MainThreadBound` once that is possible in `static`s.
struct StaticMainThreadBound<T>(T);

impl<T> StaticMainThreadBound<T> {
const fn get(&self, _mtm: MainThreadMarker) -> &T {
&self.0
}
}

unsafe impl<T> Send for StaticMainThreadBound<T> {}
unsafe impl<T> Sync for StaticMainThreadBound<T> {}

// SAFETY: Creating `StaticMainThreadBound` in a `const` context, where there is no concept
// of the main thread.
static GLOBAL: StaticMainThreadBound<OnceCell<EventHandler>> =
StaticMainThreadBound(OnceCell::new());
static GLOBAL: MainThreadBound<OnceCell<EventHandler>> =
MainThreadBound::new(OnceCell::new(), unsafe { MainThreadMarker::new_unchecked() });

GLOBAL.get(mtm).get_or_init(EventHandler::new)
}
Expand Down

0 comments on commit 8afd509

Please sign in to comment.