mirror of
https://github.com/danbulant/cushy
synced 2026-05-24 12:28:23 +00:00
Fixing Gooey compilation on MacOS
After trying to run Gooey again on my Mac for the first time in a few weeks, I found that I ran into the Condvar issue again. Rather than pasting AssertUnwindSafe in those files, I've both reported the discrepency in unwind safety (rust-lang/rust#118009) and moved the workaround into a type that only uses AssertUnwindsafe when compiling for Apple.
This commit is contained in:
parent
c39f8f33ad
commit
01d45a836f
4 changed files with 43 additions and 16 deletions
|
|
@ -44,7 +44,7 @@ use std::fmt::{Debug, Display};
|
||||||
use std::ops::{ControlFlow, Deref, Div, Mul};
|
use std::ops::{ControlFlow, Deref, Div, Mul};
|
||||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Condvar, Mutex, MutexGuard, OnceLock};
|
use std::sync::{Arc, Mutex, MutexGuard, OnceLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
|
@ -57,11 +57,11 @@ use kludgine::Color;
|
||||||
|
|
||||||
use crate::animation::easings::Linear;
|
use crate::animation::easings::Linear;
|
||||||
use crate::styles::{Component, RequireInvalidation};
|
use crate::styles::{Component, RequireInvalidation};
|
||||||
use crate::utils::IgnorePoison;
|
use crate::utils::{IgnorePoison, UnwindsafeCondvar};
|
||||||
use crate::value::Dynamic;
|
use crate::value::Dynamic;
|
||||||
|
|
||||||
static ANIMATIONS: Mutex<Animating> = Mutex::new(Animating::new());
|
static ANIMATIONS: Mutex<Animating> = Mutex::new(Animating::new());
|
||||||
static NEW_ANIMATIONS: Condvar = Condvar::new();
|
static NEW_ANIMATIONS: UnwindsafeCondvar = UnwindsafeCondvar::new();
|
||||||
|
|
||||||
fn thread_state() -> MutexGuard<'static, Animating> {
|
fn thread_state() -> MutexGuard<'static, Animating> {
|
||||||
static THREAD: OnceLock<()> = OnceLock::new();
|
static THREAD: OnceLock<()> = OnceLock::new();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use kludgine::app::winit::event::KeyEvent;
|
use kludgine::app::winit::event::KeyEvent;
|
||||||
use kludgine::app::winit::keyboard::Key;
|
use kludgine::app::winit::keyboard::Key;
|
||||||
|
|
||||||
use crate::context::WidgetContext;
|
use crate::context::WidgetContext;
|
||||||
use crate::utils::IgnorePoison;
|
use crate::utils::{IgnorePoison, UnwindsafeCondvar};
|
||||||
use crate::value::Dynamic;
|
use crate::value::Dynamic;
|
||||||
use crate::widget::{EventHandling, HANDLED, IGNORED};
|
use crate::widget::{EventHandling, HANDLED, IGNORED};
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ impl Tick {
|
||||||
input: InputState::default(),
|
input: InputState::default(),
|
||||||
}),
|
}),
|
||||||
period: tick_every,
|
period: tick_every,
|
||||||
sync: Condvar::new(),
|
sync: UnwindsafeCondvar::new(),
|
||||||
rendered_frame: AtomicUsize::new(0),
|
rendered_frame: AtomicUsize::new(0),
|
||||||
tick_number: Dynamic::default(),
|
tick_number: Dynamic::default(),
|
||||||
});
|
});
|
||||||
|
|
@ -117,7 +117,7 @@ pub struct InputState {
|
||||||
struct TickData {
|
struct TickData {
|
||||||
state: Mutex<TickState>,
|
state: Mutex<TickState>,
|
||||||
period: Duration,
|
period: Duration,
|
||||||
sync: Condvar,
|
sync: UnwindsafeCondvar,
|
||||||
rendered_frame: AtomicUsize,
|
rendered_frame: AtomicUsize,
|
||||||
tick_number: Dynamic<u64>,
|
tick_number: Dynamic<u64>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
src/utils.rs
33
src/utils.rs
|
|
@ -1,9 +1,40 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{OnceLock, PoisonError};
|
use std::sync::{Condvar, OnceLock, PoisonError};
|
||||||
|
|
||||||
use kludgine::app::winit::event::Modifiers;
|
use kludgine::app::winit::event::Modifiers;
|
||||||
use kludgine::app::winit::keyboard::ModifiersState;
|
use kludgine::app::winit::keyboard::ModifiersState;
|
||||||
|
|
||||||
|
/// This [`Condvar`] is a wrapper that on Mac OS/iOS asserts unwind safety. On
|
||||||
|
/// all other platforms, this is a transparent wrapper around `Condvar`. See
|
||||||
|
/// <https://github.com/rust-lang/rust/issues/118009> for more information.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct UnwindsafeCondvar(
|
||||||
|
#[cfg(any(target_os = "ios", target_os = "macos"))] std::panic::AssertUnwindSafe<Condvar>,
|
||||||
|
#[cfg(not(any(target_os = "ios", target_os = "macos")))] Condvar,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Deref for UnwindsafeCondvar {
|
||||||
|
type Target = Condvar;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnwindsafeCondvar {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||||
|
{
|
||||||
|
Self(AssertUnwindSafe(Condvar::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
|
||||||
|
{
|
||||||
|
Self(Condvar::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Invokes the provided macro with a pattern that can be matched using this
|
/// Invokes the provided macro with a pattern that can be matched using this
|
||||||
/// `macro_rules!` expression: `$($type:ident $field:tt $var:ident),+`, where `$type` is an
|
/// `macro_rules!` expression: `$($type:ident $field:tt $var:ident),+`, where `$type` is an
|
||||||
/// identifier to use for the generic parameter and `$field` is the field index
|
/// identifier to use for the generic parameter and `$field` is the field index
|
||||||
|
|
|
||||||
12
src/value.rs
12
src/value.rs
|
|
@ -4,9 +4,8 @@ use std::cell::Cell;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::panic::AssertUnwindSafe;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Condvar, Mutex, MutexGuard, TryLockError};
|
use std::sync::{Arc, Mutex, MutexGuard, TryLockError};
|
||||||
use std::task::{Poll, Waker};
|
use std::task::{Poll, Waker};
|
||||||
use std::thread::ThreadId;
|
use std::thread::ThreadId;
|
||||||
|
|
||||||
|
|
@ -15,7 +14,7 @@ use intentional::Assert;
|
||||||
|
|
||||||
use crate::animation::{DynamicTransition, LinearInterpolate};
|
use crate::animation::{DynamicTransition, LinearInterpolate};
|
||||||
use crate::context::{WidgetContext, WindowHandle};
|
use crate::context::{WidgetContext, WindowHandle};
|
||||||
use crate::utils::{IgnorePoison, WithClone};
|
use crate::utils::{IgnorePoison, UnwindsafeCondvar, WithClone};
|
||||||
use crate::widget::{WidgetId, WidgetInstance};
|
use crate::widget::{WidgetId, WidgetInstance};
|
||||||
use crate::widgets::Switcher;
|
use crate::widgets::Switcher;
|
||||||
|
|
||||||
|
|
@ -40,7 +39,7 @@ impl<T> Dynamic<T> {
|
||||||
widgets: AHashSet::new(),
|
widgets: AHashSet::new(),
|
||||||
}),
|
}),
|
||||||
during_callback_state: Mutex::default(),
|
during_callback_state: Mutex::default(),
|
||||||
sync: AssertUnwindSafe(Condvar::new()),
|
sync: UnwindsafeCondvar::default(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -553,10 +552,7 @@ struct LockState {
|
||||||
struct DynamicData<T> {
|
struct DynamicData<T> {
|
||||||
state: Mutex<State<T>>,
|
state: Mutex<State<T>>,
|
||||||
during_callback_state: Mutex<Option<LockState>>,
|
during_callback_state: Mutex<Option<LockState>>,
|
||||||
|
sync: UnwindsafeCondvar,
|
||||||
// The AssertUnwindSafe is only needed on Mac. For some reason on
|
|
||||||
// Mac OS, Condvar isn't RefUnwindSafe.
|
|
||||||
sync: AssertUnwindSafe<Condvar>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> DynamicData<T> {
|
impl<T> DynamicData<T> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue