Removed UnwindSafe bounds

appit wasn't supposed to pass along this requirement
This commit is contained in:
Jonathan Johnson 2023-12-20 11:35:19 -08:00
parent 2575deecf8
commit 4e145d7f35
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
19 changed files with 94 additions and 210 deletions

View file

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Breaking Changes
- Many bounds required `UnwindSafe` due to a misunderstanding on how to handle
this trait in `appit`. All requirements for `UnwindSafe` have been removed.
## v0.1.3 (2023-12-19) ## v0.1.3 (2023-12-19)
### Added ### Added

18
Cargo.lock generated
View file

@ -90,8 +90,7 @@ dependencies = [
[[package]] [[package]]
name = "appit" name = "appit"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/khonsulabs/appit#36a413865b6ac93e04b8a32023397714a165304d"
checksum = "e3441f2d5169d7cce48f58cc16a802b6bb6e9e3edf80712ac56c681a09b92ae0"
dependencies = [ dependencies = [
"winit", "winit",
] ]
@ -1148,8 +1147,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]] [[package]]
name = "kludgine" name = "kludgine"
version = "0.6.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/khonsulabs/kludgine#bb1a2cc237b353ebd91bef62109b9bb8e3cf32e7"
checksum = "0ceffa62a08f8cf3e8fb71f2a49df69100f7817a005014db52339d958a79ced5"
dependencies = [ dependencies = [
"ahash", "ahash",
"alot", "alot",
@ -1747,9 +1745,9 @@ checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.27" version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]] [[package]]
name = "png" name = "png"
@ -1838,9 +1836,9 @@ dependencies = [
[[package]] [[package]]
name = "profiling" name = "profiling"
version = "1.0.12" version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1de09527cd2ea2c2d59fb6c2f8c1ab8c71709ed9d1b6d60b0e1c9fbb6fdcb33c" checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e"
[[package]] [[package]]
name = "qoi" name = "qoi"
@ -2131,9 +2129,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "self_cell" name = "self_cell"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e388332cd64eb80cd595a00941baf513caffae8dce9cfd0467fc9c66397dade6" checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba"
[[package]] [[package]]
name = "serde" name = "serde"

View file

@ -18,7 +18,10 @@ tracing-output = ["dep:tracing-subscriber"]
roboto-flex = [] roboto-flex = []
[dependencies] [dependencies]
kludgine = { version = "0.6.1", features = ["app"] } # kludgine = { version = "0.6.1", features = ["app"] }
kludgine = { git = "https://github.com/khonsulabs/kludgine", features = [
"app",
] }
alot = "0.3" alot = "0.3"
interner = "0.2.1" interner = "0.2.1"
kempt = "0.2.1" kempt = "0.2.1"

View file

@ -1,5 +1,3 @@
use std::panic::UnwindSafe;
use gooey::widget::{MakeWidget, MakeWidgetWithTag, WidgetTag}; use gooey::widget::{MakeWidget, MakeWidgetWithTag, WidgetTag};
use gooey::widgets::container::ContainerShadow; use gooey::widgets::container::ContainerShadow;
use gooey::widgets::layers::{OverlayBuilder, OverlayLayer}; use gooey::widgets::layers::{OverlayBuilder, OverlayLayer};
@ -54,10 +52,7 @@ fn test_widget(overlay: &OverlayLayer, is_root: bool) -> impl MakeWidget {
fn show_overlay_button( fn show_overlay_button(
label: &str, label: &str,
overlay: &OverlayLayer, overlay: &OverlayLayer,
direction_func: impl for<'a> Fn(OverlayBuilder<'a>) -> OverlayBuilder<'a> direction_func: impl for<'a> Fn(OverlayBuilder<'a>) -> OverlayBuilder<'a> + Send + 'static,
+ Send
+ UnwindSafe
+ 'static,
) -> impl MakeWidget { ) -> impl MakeWidget {
let overlay = overlay.clone(); let overlay = overlay.clone();
label.into_button().on_click(move |()| { label.into_button().on_click(move |()| {

View file

@ -42,9 +42,8 @@ pub mod easings;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::ops::{ControlFlow, Deref, Div, DivAssign, Mul, MulAssign, Sub}; use std::ops::{ControlFlow, Deref, Div, DivAssign, Mul, MulAssign, Sub};
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex, MutexGuard, OnceLock}; use std::sync::{Arc, Condvar, Mutex, MutexGuard, OnceLock};
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -57,11 +56,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::{run_in_bg, IgnorePoison, UnwindsafeCondvar}; use crate::utils::{run_in_bg, IgnorePoison};
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: UnwindsafeCondvar = UnwindsafeCondvar::new(); static NEW_ANIMATIONS: Condvar = Condvar::new();
fn thread_state() -> MutexGuard<'static, Animating> { fn thread_state() -> MutexGuard<'static, Animating> {
static THREAD: OnceLock<()> = OnceLock::new(); static THREAD: OnceLock<()> = OnceLock::new();
@ -1358,7 +1357,7 @@ impl PartialEq for EasingFunction {
} }
/// Performs easing for value interpolation. /// Performs easing for value interpolation.
pub trait Easing: Debug + Send + Sync + RefUnwindSafe + UnwindSafe + 'static { pub trait Easing: Debug + Send + Sync + 'static {
/// Eases a value ranging between zero and one. The resulting value does not /// Eases a value ranging between zero and one. The resulting value does not
/// need to be bounded between zero and one. /// need to be bounded between zero and one.
fn ease(&self, progress: ZeroToOne) -> f32; fn ease(&self, progress: ZeroToOne) -> f32;

View file

@ -8,7 +8,6 @@ use std::ops::{
Add, AddAssign, Bound, Deref, Div, Mul, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, Add, AddAssign, Bound, Deref, Div, Mul, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
RangeToInclusive, RangeToInclusive,
}; };
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::sync::Arc; use std::sync::Arc;
use ahash::AHashMap; use ahash::AHashMap;
@ -374,7 +373,7 @@ impl IntoDynamicComponentValue for DynamicComponent {
impl<T> IntoDynamicComponentValue for T impl<T> IntoDynamicComponentValue for T
where where
T: ComponentDefinition + Clone + RefUnwindSafe + Send + Sync + 'static, T: ComponentDefinition + Clone + Send + Sync + 'static,
{ {
fn into_dynamic_component(self) -> Value<DynamicComponent> { fn into_dynamic_component(self) -> Value<DynamicComponent> {
Value::Constant(DynamicComponent::from(self)) Value::Constant(DynamicComponent::from(self))
@ -383,7 +382,7 @@ where
impl<T> IntoDynamicComponentValue for Dynamic<T> impl<T> IntoDynamicComponentValue for Dynamic<T>
where where
T: ComponentDefinition + Clone + RefUnwindSafe + Send + Sync + 'static, T: ComponentDefinition + Clone + Send + Sync + 'static,
{ {
fn into_dynamic_component(self) -> Value<DynamicComponent> { fn into_dynamic_component(self) -> Value<DynamicComponent> {
Value::Dynamic(self.map_each_into()) Value::Dynamic(self.map_each_into())
@ -430,7 +429,7 @@ impl Component {
/// Custom components allow storing nearly any type in the style system. /// Custom components allow storing nearly any type in the style system.
pub fn custom<T>(component: T) -> Self pub fn custom<T>(component: T) -> Self
where where
T: RequireInvalidation + RefUnwindSafe + UnwindSafe + Debug + Send + Sync + 'static, T: RequireInvalidation + Debug + Send + Sync + 'static,
{ {
Self::Custom(CustomComponent::new(component)) Self::Custom(CustomComponent::new(component))
} }
@ -441,7 +440,6 @@ impl Component {
pub fn dynamic<T, Func>(resolve: Func) -> Self pub fn dynamic<T, Func>(resolve: Func) -> Self
where where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<T> Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<T>
+ RefUnwindSafe
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
@ -617,7 +615,7 @@ impl RequireInvalidation for Lp {
impl<Unit> From<CornerRadii<Unit>> for Component impl<Unit> From<CornerRadii<Unit>> for Component
where where
Dimension: From<Unit>, Dimension: From<Unit>,
Unit: Debug + UnwindSafe + RefUnwindSafe + Send + Sync + 'static, Unit: Debug + Send + Sync + 'static,
{ {
fn from(radii: CornerRadii<Unit>) -> Self { fn from(radii: CornerRadii<Unit>) -> Self {
let radii = CornerRadii { let radii = CornerRadii {
@ -1002,7 +1000,7 @@ impl CustomComponent {
/// Wraps an arbitrary value so that it can be used as a [`Component`]. /// Wraps an arbitrary value so that it can be used as a [`Component`].
pub fn new<T>(value: T) -> Self pub fn new<T>(value: T) -> Self
where where
T: RequireInvalidation + RefUnwindSafe + UnwindSafe + Debug + Send + Sync + 'static, T: RequireInvalidation + Debug + Send + Sync + 'static,
{ {
Self(Arc::new(value)) Self(Arc::new(value))
} }
@ -1043,13 +1041,13 @@ impl ComponentType for CustomComponent {
} }
} }
trait AnyComponent: RequireInvalidation + Send + Sync + RefUnwindSafe + UnwindSafe + Debug { trait AnyComponent: RequireInvalidation + Send + Sync + Debug {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
} }
impl<T> AnyComponent for T impl<T> AnyComponent for T
where where
T: RequireInvalidation + RefUnwindSafe + UnwindSafe + Debug + Send + Sync + 'static, T: RequireInvalidation + Debug + Send + Sync + 'static,
{ {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
@ -2534,7 +2532,7 @@ impl PartialEq for DynamicComponent {
} }
/// A type that resolves to a [`Component`] at runtime. /// A type that resolves to a [`Component`] at runtime.
pub trait DynamicComponentResolver: RefUnwindSafe + Send + Sync + 'static { pub trait DynamicComponentResolver: Send + Sync + 'static {
/// Returns the effective component, if one should be applied. /// Returns the effective component, if one should be applied.
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component>; fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component>;
} }
@ -2544,7 +2542,6 @@ struct DynamicFunctionWrapper<F>(F);
impl<T> DynamicComponentResolver for DynamicFunctionWrapper<T> impl<T> DynamicComponentResolver for DynamicFunctionWrapper<T>
where where
T: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component> T: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component>
+ RefUnwindSafe
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
@ -2556,7 +2553,7 @@ where
impl<T> DynamicComponentResolver for T impl<T> DynamicComponentResolver for T
where where
T: ComponentDefinition + Clone + RefUnwindSafe + Send + Sync + 'static, T: ComponentDefinition + Clone + Send + Sync + 'static,
{ {
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> { fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> {
Some(context.get(self).into_component()) Some(context.get(self).into_component())
@ -2579,7 +2576,6 @@ impl DynamicComponent {
pub fn new<Func>(resolve: Func) -> Self pub fn new<Func>(resolve: Func) -> Self
where where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component> Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component>
+ RefUnwindSafe
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,

View file

@ -1,5 +1,5 @@
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Condvar, Mutex, MutexGuard};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use ahash::AHashSet; use ahash::AHashSet;
@ -10,7 +10,7 @@ use kludgine::figures::units::Px;
use kludgine::figures::Point; use kludgine::figures::Point;
use crate::context::WidgetContext; use crate::context::WidgetContext;
use crate::utils::{IgnorePoison, UnwindsafeCondvar}; use crate::utils::IgnorePoison;
use crate::value::Dynamic; use crate::value::Dynamic;
use crate::widget::{EventHandling, HANDLED, IGNORED}; use crate::widget::{EventHandling, HANDLED, IGNORED};
@ -102,7 +102,7 @@ impl Tick {
input: InputState::default(), input: InputState::default(),
}), }),
period: tick_every, period: tick_every,
sync: UnwindsafeCondvar::new(), sync: Condvar::new(),
rendered_frame: AtomicUsize::new(0), rendered_frame: AtomicUsize::new(0),
tick_number: Dynamic::default(), tick_number: Dynamic::default(),
}); });
@ -162,7 +162,7 @@ pub struct Mouse {
struct TickData { struct TickData {
state: Mutex<TickState>, state: Mutex<TickState>,
period: Duration, period: Duration,
sync: UnwindsafeCondvar, sync: Condvar,
rendered_frame: AtomicUsize, rendered_frame: AtomicUsize,
tick_number: Dynamic<u64>, tick_number: Dynamic<u64>,
} }

View file

@ -1,42 +1,11 @@
use std::ops::Deref; use std::ops::Deref;
use std::sync::mpsc::{self, SyncSender}; use std::sync::mpsc::{self, SyncSender};
use std::sync::{Condvar, OnceLock, PoisonError}; use std::sync::{OnceLock, PoisonError};
use intentional::Assert; use intentional::Assert;
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/Windows 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", target_os = "windows"))] std::panic::AssertUnwindSafe<Condvar>,
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "windows")))] 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", target_os = "windows"))]
{
Self(std::panic::AssertUnwindSafe(Condvar::new()))
}
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "windows")))]
{
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

View file

@ -5,9 +5,8 @@ use std::fmt::{self, Debug, Display};
use std::future::Future; use std::future::Future;
use std::hash::{BuildHasher, Hash}; use std::hash::{BuildHasher, Hash};
use std::ops::{Deref, DerefMut, Not}; use std::ops::{Deref, DerefMut, Not};
use std::panic::UnwindSafe;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex, MutexGuard, TryLockError, Weak}; use std::sync::{Arc, Condvar, Mutex, MutexGuard, TryLockError, Weak};
use std::task::{Poll, Waker}; use std::task::{Poll, Waker};
use std::thread::{self, ThreadId}; use std::thread::{self, ThreadId};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -20,7 +19,7 @@ use kempt::{Map, Sort};
use crate::animation::{AnimationHandle, DynamicTransition, IntoAnimate, LinearInterpolate, Spawn}; use crate::animation::{AnimationHandle, DynamicTransition, IntoAnimate, LinearInterpolate, Spawn};
use crate::context::sealed::WindowHandle; use crate::context::sealed::WindowHandle;
use crate::context::{self, WidgetContext}; use crate::context::{self, WidgetContext};
use crate::utils::{run_in_bg, IgnorePoison, UnwindsafeCondvar, WithClone}; use crate::utils::{run_in_bg, IgnorePoison, WithClone};
use crate::widget::{Children, MakeWidget, MakeWidgetWithTag, WidgetId, WidgetInstance}; use crate::widget::{Children, MakeWidget, MakeWidgetWithTag, WidgetId, WidgetInstance};
use crate::widgets::{Radio, Select, Space, Switcher}; use crate::widgets::{Radio, Select, Space, Switcher};
@ -45,7 +44,7 @@ impl<T> Dynamic<T> {
source_callback: None, source_callback: None,
}), }),
during_callback_state: Mutex::default(), during_callback_state: Mutex::default(),
sync: UnwindsafeCondvar::default(), sync: Condvar::default(),
})) }))
} }
@ -759,7 +758,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, sync: Condvar,
} }
impl<T> DynamicData<T> { impl<T> DynamicData<T> {
@ -998,7 +997,7 @@ where
struct ChangeCallbacksData { struct ChangeCallbacksData {
callbacks: Mutex<CallbacksList>, callbacks: Mutex<CallbacksList>,
currently_executing: Mutex<Option<ThreadId>>, currently_executing: Mutex<Option<ThreadId>>,
sync: UnwindsafeCondvar, sync: Condvar,
} }
struct CallbacksList { struct CallbacksList {
@ -2319,7 +2318,7 @@ impl Validations {
fn invoke_callback<T, R, F>(&self, t: T, handler: &mut F) -> R fn invoke_callback<T, R, F>(&self, t: T, handler: &mut F) -> R
where where
F: FnMut(T) -> R + UnwindSafe + Send + 'static, F: FnMut(T) -> R + Send + 'static,
R: Default, R: Default,
{ {
let mut state = self.state.lock(); let mut state = self.state.lock();
@ -2341,12 +2340,9 @@ impl Validations {
/// [`Callback`](crate::widget::Callback). /// [`Callback`](crate::widget::Callback).
/// ///
/// When the contents are invalid, `R::default()` is returned. /// When the contents are invalid, `R::default()` is returned.
pub fn when_valid<T, R, F>( pub fn when_valid<T, R, F>(self, mut handler: F) -> impl FnMut(T) -> R + Send + 'static
self,
mut handler: F,
) -> impl FnMut(T) -> R + UnwindSafe + Send + 'static
where where
F: FnMut(T) -> R + UnwindSafe + Send + 'static, F: FnMut(T) -> R + Send + 'static,
R: Default, R: Default,
{ {
move |t: T| self.invoke_callback(t, &mut handler) move |t: T| self.invoke_callback(t, &mut handler)

View file

@ -4,7 +4,6 @@ use std::any::Any;
use std::clone::Clone; use std::clone::Clone;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::ops::{ControlFlow, Deref, DerefMut}; use std::ops::{ControlFlow, Deref, DerefMut};
use std::panic::UnwindSafe;
use std::sync::atomic::{self, AtomicU64}; use std::sync::atomic::{self, AtomicU64};
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use std::{slice, vec}; use std::{slice, vec};
@ -260,7 +259,7 @@ use crate::{ConstraintLimit, Run};
/// the color system works in Gooey. /// the color system works in Gooey.
/// ///
/// [repo]: https://github.com/khonsulabs/gooey /// [repo]: https://github.com/khonsulabs/gooey
pub trait Widget: Send + UnwindSafe + Debug + 'static { pub trait Widget: Send + Debug + 'static {
/// Redraw the contents of this widget. /// Redraw the contents of this widget.
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>);
@ -509,7 +508,7 @@ impl From<Size<UPx>> for WrappedLayout {
} }
/// A [`Widget`] that contains a single child. /// A [`Widget`] that contains a single child.
pub trait WrapperWidget: Debug + Send + UnwindSafe + 'static { pub trait WrapperWidget: Debug + Send + 'static {
/// Returns the child widget. /// Returns the child widget.
fn child_mut(&mut self) -> &mut WidgetRef; fn child_mut(&mut self) -> &mut WidgetRef;
@ -1603,7 +1602,7 @@ impl<T, R> Callback<T, R> {
/// invoked. /// invoked.
pub fn new<F>(function: F) -> Self pub fn new<F>(function: F) -> Self
where where
F: FnMut(T) -> R + Send + UnwindSafe + 'static, F: FnMut(T) -> R + Send + 'static,
{ {
Self(Box::new(function)) Self(Box::new(function))
} }
@ -1614,13 +1613,13 @@ impl<T, R> Callback<T, R> {
} }
} }
trait CallbackFunction<T, R>: Send + UnwindSafe { trait CallbackFunction<T, R>: Send {
fn invoke(&mut self, value: T) -> R; fn invoke(&mut self, value: T) -> R;
} }
impl<T, R, F> CallbackFunction<T, R> for F impl<T, R, F> CallbackFunction<T, R> for F
where where
F: FnMut(T) -> R + Send + UnwindSafe, F: FnMut(T) -> R + Send,
{ {
fn invoke(&mut self, value: T) -> R { fn invoke(&mut self, value: T) -> R {
self(value) self(value)
@ -1653,7 +1652,7 @@ impl<T, R> OnceCallback<T, R> {
/// invoked. /// invoked.
pub fn new<F>(function: F) -> Self pub fn new<F>(function: F) -> Self
where where
F: FnOnce(T) -> R + Send + UnwindSafe + 'static, F: FnOnce(T) -> R + Send + 'static,
{ {
Self(Box::new(Some(function))) Self(Box::new(Some(function)))
} }
@ -1664,13 +1663,13 @@ impl<T, R> OnceCallback<T, R> {
} }
} }
trait OnceCallbackFunction<T, R>: Send + UnwindSafe { trait OnceCallbackFunction<T, R>: Send {
fn invoke(&mut self, value: T) -> R; fn invoke(&mut self, value: T) -> R;
} }
impl<T, R, F> OnceCallbackFunction<T, R> for Option<F> impl<T, R, F> OnceCallbackFunction<T, R> for Option<F>
where where
F: FnOnce(T) -> R + Send + UnwindSafe, F: FnOnce(T) -> R + Send,
{ {
fn invoke(&mut self, value: T) -> R { fn invoke(&mut self, value: T) -> R {
(self.take().assert("invoked once"))(value) (self.take().assert("invoked once"))(value)

View file

@ -1,5 +1,4 @@
//! A clickable, labeled button //! A clickable, labeled button
use std::panic::UnwindSafe;
use std::time::Duration; use std::time::Duration;
use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton}; use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton};
@ -158,7 +157,7 @@ impl Button {
#[must_use] #[must_use]
pub fn on_click<F>(mut self, callback: F) -> Self pub fn on_click<F>(mut self, callback: F) -> Self
where where
F: FnMut(()) + Send + UnwindSafe + 'static, F: FnMut(()) + Send + 'static,
{ {
self.on_click = Some(Callback::new(callback)); self.on_click = Some(Callback::new(callback));
self self

View file

@ -1,5 +1,4 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::panic::UnwindSafe;
use kludgine::figures::units::UPx; use kludgine::figures::units::UPx;
use kludgine::figures::Size; use kludgine::figures::Size;
@ -24,7 +23,6 @@ impl Canvas {
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut( F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
) + Send ) + Send
+ UnwindSafe
+ 'static, + 'static,
{ {
Self { Self {
@ -65,7 +63,7 @@ impl Debug for Canvas {
} }
} }
trait RenderFunction: Send + UnwindSafe + 'static { trait RenderFunction: Send + 'static {
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>);
} }
@ -74,7 +72,6 @@ where
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut( F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
) + Send ) + Send
+ UnwindSafe
+ 'static, + 'static,
{ {
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {

View file

@ -1,5 +1,4 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::panic::UnwindSafe;
use kludgine::app::winit::event::{ use kludgine::app::winit::event::{
DeviceId, Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase, DeviceId, Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase,
@ -121,7 +120,6 @@ impl Custom {
pub fn on_redraw<Redraw>(mut self, redraw: Redraw) -> Self pub fn on_redraw<Redraw>(mut self, redraw: Redraw) -> Self
where where
Redraw: Send Redraw: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
@ -144,7 +142,6 @@ impl Custom {
pub fn on_redraw_after_child<Redraw>(mut self, redraw: Redraw) -> Self pub fn on_redraw_after_child<Redraw>(mut self, redraw: Redraw) -> Self
where where
Redraw: Send Redraw: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
@ -159,10 +156,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::mounted`]. /// This callback corresponds to [`WrapperWidget::mounted`].
pub fn on_mounted<Mounted>(mut self, mounted: Mounted) -> Self pub fn on_mounted<Mounted>(mut self, mounted: Mounted) -> Self
where where
Mounted: Send Mounted:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.mounted = Some(Box::new(mounted)); self.mounted = Some(Box::new(mounted));
self self
@ -174,10 +169,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::unmounted`]. /// This callback corresponds to [`WrapperWidget::unmounted`].
pub fn on_unmounted<Mounted>(mut self, mounted: Mounted) -> Self pub fn on_unmounted<Mounted>(mut self, mounted: Mounted) -> Self
where where
Mounted: Send Mounted:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.unmounted = Some(Box::new(mounted)); self.unmounted = Some(Box::new(mounted));
self self
@ -188,10 +181,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::unhover`]. /// This callback corresponds to [`WrapperWidget::unhover`].
pub fn on_unhover<Unhover>(mut self, unhovered: Unhover) -> Self pub fn on_unhover<Unhover>(mut self, unhovered: Unhover) -> Self
where where
Unhover: Send Unhover:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.unhover = Some(Box::new(unhovered)); self.unhover = Some(Box::new(unhovered));
self self
@ -202,10 +193,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::focus`]. /// This callback corresponds to [`WrapperWidget::focus`].
pub fn on_focus<Focused>(mut self, focus: Focused) -> Self pub fn on_focus<Focused>(mut self, focus: Focused) -> Self
where where
Focused: Send Focused:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.focus = Some(Box::new(focus)); self.focus = Some(Box::new(focus));
self self
@ -216,10 +205,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::blur`]. /// This callback corresponds to [`WrapperWidget::blur`].
pub fn on_blur<Blur>(mut self, blur: Blur) -> Self pub fn on_blur<Blur>(mut self, blur: Blur) -> Self
where where
Blur: Send Blur: Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ UnwindSafe
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.blur = Some(Box::new(blur)); self.blur = Some(Box::new(blur));
self self
@ -230,10 +216,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::activate`]. /// This callback corresponds to [`WrapperWidget::activate`].
pub fn on_activate<Activated>(mut self, activated: Activated) -> Self pub fn on_activate<Activated>(mut self, activated: Activated) -> Self
where where
Activated: Send Activated:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.activate = Some(Box::new(activated)); self.activate = Some(Box::new(activated));
self self
@ -244,10 +228,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::deactivate`]. /// This callback corresponds to [`WrapperWidget::deactivate`].
pub fn on_deactivate<Deactivated>(mut self, deactivated: Deactivated) -> Self pub fn on_deactivate<Deactivated>(mut self, deactivated: Deactivated) -> Self
where where
Deactivated: Send Deactivated:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.deactivate = Some(Box::new(deactivated)); self.deactivate = Some(Box::new(deactivated));
self self
@ -260,7 +242,6 @@ impl Custom {
pub fn on_accept_focus<AcceptFocus>(mut self, accept: AcceptFocus) -> Self pub fn on_accept_focus<AcceptFocus>(mut self, accept: AcceptFocus) -> Self
where where
AcceptFocus: Send AcceptFocus: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool, + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool,
{ {
@ -276,7 +257,6 @@ impl Custom {
pub fn on_allow_blur<AllowBlur>(mut self, allow_blur: AllowBlur) -> Self pub fn on_allow_blur<AllowBlur>(mut self, allow_blur: AllowBlur) -> Self
where where
AllowBlur: Send AllowBlur: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool, + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool,
{ {
@ -293,7 +273,6 @@ impl Custom {
pub fn on_advance_focus<AdvanceFocus>(mut self, advance_focus: AdvanceFocus) -> Self pub fn on_advance_focus<AdvanceFocus>(mut self, advance_focus: AdvanceFocus) -> Self
where where
AdvanceFocus: Send AdvanceFocus: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
VisualOrder, VisualOrder,
@ -315,7 +294,6 @@ impl Custom {
) -> Self ) -> Self
where where
AdjustChildConstraints: Send AdjustChildConstraints: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
Size<ConstraintLimit>, Size<ConstraintLimit>,
@ -332,7 +310,6 @@ impl Custom {
pub fn on_position_child<PositionChild>(mut self, position_child: PositionChild) -> Self pub fn on_position_child<PositionChild>(mut self, position_child: PositionChild) -> Self
where where
PositionChild: Send PositionChild: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
Size<Px>, Size<Px>,
@ -351,7 +328,6 @@ impl Custom {
pub fn on_hit_test<HitTest>(mut self, hit_test: HitTest) -> Self pub fn on_hit_test<HitTest>(mut self, hit_test: HitTest) -> Self
where where
HitTest: Send HitTest: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut(Point<Px>, &mut EventContext<'context, 'window>) -> bool, + for<'context, 'window> FnMut(Point<Px>, &mut EventContext<'context, 'window>) -> bool,
{ {
@ -365,7 +341,6 @@ impl Custom {
pub fn on_hover<Hover>(mut self, hover: Hover) -> Self pub fn on_hover<Hover>(mut self, hover: Hover) -> Self
where where
Hover: Send Hover: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
Point<Px>, Point<Px>,
@ -388,7 +363,6 @@ impl Custom {
pub fn on_mouse_down<MouseDown>(mut self, mouse_down: MouseDown) -> Self pub fn on_mouse_down<MouseDown>(mut self, mouse_down: MouseDown) -> Self
where where
MouseDown: Send MouseDown: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
Point<Px>, Point<Px>,
@ -408,7 +382,6 @@ impl Custom {
pub fn on_mouse_drag<MouseDrag>(mut self, mouse_drag: MouseDrag) -> Self pub fn on_mouse_drag<MouseDrag>(mut self, mouse_drag: MouseDrag) -> Self
where where
MouseDrag: Send MouseDrag: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
Point<Px>, Point<Px>,
@ -427,7 +400,6 @@ impl Custom {
pub fn on_mouse_up<MouseUp>(mut self, mouse_up: MouseUp) -> Self pub fn on_mouse_up<MouseUp>(mut self, mouse_up: MouseUp) -> Self
where where
MouseUp: Send MouseUp: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
Option<Point<Px>>, Option<Point<Px>>,
@ -446,7 +418,6 @@ impl Custom {
pub fn on_ime<OnIme>(mut self, ime: OnIme) -> Self pub fn on_ime<OnIme>(mut self, ime: OnIme) -> Self
where where
OnIme: Send OnIme: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut(Ime, &mut EventContext<'context, 'window>) -> EventHandling, + for<'context, 'window> FnMut(Ime, &mut EventContext<'context, 'window>) -> EventHandling,
{ {
@ -460,7 +431,6 @@ impl Custom {
pub fn on_keyboard_input<KeyboardInput>(mut self, keyboard_input: KeyboardInput) -> Self pub fn on_keyboard_input<KeyboardInput>(mut self, keyboard_input: KeyboardInput) -> Self
where where
KeyboardInput: Send KeyboardInput: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
DeviceId, DeviceId,
@ -479,7 +449,6 @@ impl Custom {
pub fn mouse_wheel<MouseWheel>(mut self, mouse_wheel: MouseWheel) -> Self pub fn mouse_wheel<MouseWheel>(mut self, mouse_wheel: MouseWheel) -> Self
where where
MouseWheel: Send MouseWheel: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context, 'window> FnMut(
DeviceId, DeviceId,
@ -711,14 +680,13 @@ impl WrapperWidget for Custom {
} }
} }
trait RedrawFunc: Send + UnwindSafe { trait RedrawFunc: Send {
fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>);
} }
impl<Func> RedrawFunc for Func impl<Func> RedrawFunc for Func
where where
Func: Send Func: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
@ -729,7 +697,7 @@ where
} }
} }
trait AdjustChildConstraintsFunc: Send + UnwindSafe { trait AdjustChildConstraintsFunc: Send {
fn invoke( fn invoke(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
@ -740,7 +708,6 @@ trait AdjustChildConstraintsFunc: Send + UnwindSafe {
impl<Func> AdjustChildConstraintsFunc for Func impl<Func> AdjustChildConstraintsFunc for Func
where where
Func: Send Func: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
Size<ConstraintLimit>, Size<ConstraintLimit>,
@ -756,7 +723,7 @@ where
} }
} }
trait PositionChildFunc: Send + UnwindSafe { trait PositionChildFunc: Send {
fn invoke( fn invoke(
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
@ -768,7 +735,6 @@ trait PositionChildFunc: Send + UnwindSafe {
impl<Func> PositionChildFunc for Func impl<Func> PositionChildFunc for Func
where where
Func: Send Func: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'window, 'clip, 'gfx, 'pass> FnMut(
Size<Px>, Size<Px>,
@ -786,39 +752,34 @@ where
} }
} }
trait EventFunc<R = ()>: Send + UnwindSafe { trait EventFunc<R = ()>: Send {
fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R; fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R;
} }
impl<R, Func> EventFunc<R> for Func impl<R, Func> EventFunc<R> for Func
where where
Func: Send Func: Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> R,
+ UnwindSafe
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> R,
{ {
fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R { fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R {
self(context) self(context)
} }
} }
trait OneParamEventFunc<P, R = ()>: Send + UnwindSafe { trait OneParamEventFunc<P, R = ()>: Send {
fn invoke(&mut self, param: P, context: &mut EventContext<'_, '_>) -> R; fn invoke(&mut self, param: P, context: &mut EventContext<'_, '_>) -> R;
} }
impl<P, R, Func> OneParamEventFunc<P, R> for Func impl<P, R, Func> OneParamEventFunc<P, R> for Func
where where
Func: Send Func:
+ UnwindSafe Send + 'static + for<'context, 'window> FnMut(P, &mut EventContext<'context, 'window>) -> R,
+ 'static
+ for<'context, 'window> FnMut(P, &mut EventContext<'context, 'window>) -> R,
{ {
fn invoke(&mut self, location: P, context: &mut EventContext<'_, '_>) -> R { fn invoke(&mut self, location: P, context: &mut EventContext<'_, '_>) -> R {
self(location, context) self(location, context)
} }
} }
trait ThreeParamEventFunc<P1, P2, P3, R = ()>: Send + UnwindSafe { trait ThreeParamEventFunc<P1, P2, P3, R = ()>: Send {
fn invoke( fn invoke(
&mut self, &mut self,
location: P1, location: P1,
@ -833,7 +794,6 @@ type MouseUpFunc = dyn ThreeParamEventFunc<Option<Point<Px>>, DeviceId, MouseBut
impl<P1, P2, P3, R, Func> ThreeParamEventFunc<P1, P2, P3, R> for Func impl<P1, P2, P3, R, Func> ThreeParamEventFunc<P1, P2, P3, R> for Func
where where
Func: Send Func: Send
+ UnwindSafe
+ 'static + 'static
+ for<'context, 'window> FnMut(P1, P2, P3, &mut EventContext<'context, 'window>) -> R, + for<'context, 'window> FnMut(P1, P2, P3, &mut EventContext<'context, 'window>) -> R,
{ {

View file

@ -1,5 +1,4 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::panic::UnwindSafe;
use crate::widget::{MakeWidget, WidgetRef, WrapperWidget}; use crate::widget::{MakeWidget, WidgetRef, WrapperWidget};
use crate::widgets::Space; use crate::widgets::Space;
@ -48,7 +47,7 @@ where
impl<T> WrapperWidget for Data<T> impl<T> WrapperWidget for Data<T>
where where
T: Debug + Send + UnwindSafe + 'static, T: Debug + Send + 'static,
{ {
fn child_mut(&mut self) -> &mut WidgetRef { fn child_mut(&mut self) -> &mut WidgetRef {
&mut self.child &mut self.child

View file

@ -5,7 +5,6 @@ use std::cmp::Ordering;
use std::fmt::{self, Debug, Display, Formatter, Write}; use std::fmt::{self, Debug, Display, Formatter, Write};
use std::hash::Hash; use std::hash::Hash;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::panic::UnwindSafe;
use std::sync::{Arc, OnceLock}; use std::sync::{Arc, OnceLock};
use std::time::Duration; use std::time::Duration;
@ -163,7 +162,7 @@ where
/// is returned, this widget will ignore the event. /// is returned, this widget will ignore the event.
pub fn on_key<F>(mut self, on_key: F) -> Self pub fn on_key<F>(mut self, on_key: F) -> Self
where where
F: FnMut(KeyEvent) -> EventHandling + Send + UnwindSafe + 'static, F: FnMut(KeyEvent) -> EventHandling + Send + 'static,
{ {
self.on_key = Some(Callback::new(on_key)); self.on_key = Some(Callback::new(on_key));
self self
@ -1280,7 +1279,7 @@ impl BlinkState {
/// - `Cow<'static, str>` /// - `Cow<'static, str>`
/// - [`CowString`] /// - [`CowString`]
/// - [`MaskedString`] /// - [`MaskedString`]
pub trait InputStorage: UnwindSafe + Send + 'static { pub trait InputStorage: Send + 'static {
/// If true, the input field should display a mask instead of the actual /// If true, the input field should display a mask instead of the actual
/// string by default. /// string by default.
const MASKED: bool; const MASKED: bool;

View file

@ -1,6 +1,5 @@
//! A labeled widget with a circular indicator representing a value. //! A labeled widget with a circular indicator representing a value.
use std::fmt::Debug; use std::fmt::Debug;
use std::panic::UnwindSafe;
use kludgine::figures::units::Lp; use kludgine::figures::units::Lp;
use kludgine::figures::{Point, ScreenScale, Size}; use kludgine::figures::{Point, ScreenScale, Size};
@ -53,7 +52,7 @@ impl<T> Radio<T> {
impl<T> MakeWidgetWithTag for Radio<T> impl<T> MakeWidgetWithTag for Radio<T>
where where
T: Clone + Debug + Eq + UnwindSafe + Send + 'static, T: Clone + Debug + Eq + Send + 'static,
{ {
fn make_with_tag(self, id: crate::widget::WidgetTag) -> WidgetInstance { fn make_with_tag(self, id: crate::widget::WidgetTag) -> WidgetInstance {
RadioOrnament { RadioOrnament {
@ -79,7 +78,7 @@ struct RadioOrnament<T> {
impl<T> Widget for RadioOrnament<T> impl<T> Widget for RadioOrnament<T>
where where
T: Debug + Eq + UnwindSafe + Send + 'static, T: Debug + Eq + Send + 'static,
{ {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
let radio_size = context let radio_size = context

View file

@ -1,6 +1,5 @@
//! A selectable, labeled widget representing a value. //! A selectable, labeled widget representing a value.
use std::fmt::Debug; use std::fmt::Debug;
use std::panic::{RefUnwindSafe, UnwindSafe};
use kludgine::Color; use kludgine::Color;
@ -48,7 +47,7 @@ impl<T> Select<T> {
impl<T> MakeWidgetWithTag for Select<T> impl<T> MakeWidgetWithTag for Select<T>
where where
T: Clone + Debug + Eq + RefUnwindSafe + UnwindSafe + Send + Sync + 'static, T: Clone + Debug + Eq + Send + Sync + 'static,
{ {
fn make_with_tag(self, id: crate::widget::WidgetTag) -> WidgetInstance { fn make_with_tag(self, id: crate::widget::WidgetTag) -> WidgetInstance {
let selected = self.state.map_each({ let selected = self.state.map_each({

View file

@ -2,7 +2,6 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::mem; use std::mem;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use std::panic::UnwindSafe;
use intentional::{Assert, Cast as _}; use intentional::{Assert, Cast as _};
use kludgine::app::winit::event::{DeviceId, MouseButton, MouseScrollDelta, TouchPhase}; use kludgine::app::winit::event::{DeviceId, MouseButton, MouseScrollDelta, TouchPhase};
@ -786,16 +785,9 @@ define_components! {
} }
/// A value that can be used in a [`Slider`] widget. /// A value that can be used in a [`Slider`] widget.
pub trait SliderValue: Clone + PartialEq + UnwindSafe + Send + Debug + 'static { pub trait SliderValue: Clone + PartialEq + Send + Debug + 'static {
/// The component value for the slider. /// The component value for the slider.
type Value: Clone type Value: Clone + Debug + PartialOrd + LinearInterpolate + PercentBetween + Send + 'static;
+ Debug
+ PartialOrd
+ LinearInterpolate
+ PercentBetween
+ UnwindSafe
+ Send
+ 'static;
/// When true, this type is expected to represent two values: start and an /// When true, this type is expected to represent two values: start and an
/// end. /// end.
const RANGED: bool; const RANGED: bool;
@ -808,14 +800,7 @@ pub trait SliderValue: Clone + PartialEq + UnwindSafe + Send + Debug + 'static {
impl<T> SliderValue for T impl<T> SliderValue for T
where where
T: Clone T: Clone + Debug + PartialOrd + LinearInterpolate + PercentBetween + Send + 'static,
+ Debug
+ PartialOrd
+ LinearInterpolate
+ PercentBetween
+ UnwindSafe
+ Send
+ 'static,
{ {
type Value = T; type Value = T;
@ -832,14 +817,7 @@ where
impl<T> SliderValue for RangeInclusive<T> impl<T> SliderValue for RangeInclusive<T>
where where
T: Clone T: Clone + Debug + PartialOrd + LinearInterpolate + PercentBetween + Send + 'static,
+ Debug
+ PartialOrd
+ LinearInterpolate
+ PercentBetween
+ UnwindSafe
+ Send
+ 'static,
{ {
type Value = T; type Value = T;
@ -857,14 +835,7 @@ where
impl<T> SliderValue for (T, T) impl<T> SliderValue for (T, T)
where where
T: Clone T: Clone + Debug + PartialOrd + LinearInterpolate + PercentBetween + Send + 'static,
+ Debug
+ PartialOrd
+ LinearInterpolate
+ PercentBetween
+ UnwindSafe
+ Send
+ 'static,
{ {
type Value = T; type Value = T;

View file

@ -3,7 +3,6 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::ops::{Deref, DerefMut, Not}; use std::ops::{Deref, DerefMut, Not};
use std::panic::{AssertUnwindSafe, UnwindSafe};
use std::path::Path; use std::path::Path;
use std::string::ToString; use std::string::ToString;
use std::sync::{MutexGuard, OnceLock}; use std::sync::{MutexGuard, OnceLock};
@ -309,7 +308,7 @@ where
{ {
fn run(self) -> crate::Result { fn run(self) -> crate::Result {
initialize_tracing(); initialize_tracing();
GooeyWindow::<Behavior>::run_with(AssertUnwindSafe(sealed::Context { GooeyWindow::<Behavior>::run_with(sealed::Context {
user: self.context, user: self.context,
settings: RefCell::new(sealed::WindowSettings { settings: RefCell::new(sealed::WindowSettings {
gooey: self.gooey, gooey: self.gooey,
@ -327,14 +326,14 @@ where
monospace_font_family: self.monospace_font_family, monospace_font_family: self.monospace_font_family,
cursive_font_family: self.cursive_font_family, cursive_font_family: self.cursive_font_family,
}), }),
})) })
} }
} }
/// The behavior of a Gooey window. /// The behavior of a Gooey window.
pub trait WindowBehavior: Sized + 'static { pub trait WindowBehavior: Sized + 'static {
/// The type that is provided when initializing this window. /// The type that is provided when initializing this window.
type Context: UnwindSafe + Send + 'static; type Context: Send + 'static;
/// Return a new instance of this behavior using `context`. /// Return a new instance of this behavior using `context`.
fn initialize(window: &mut RunningWindow<'_>, context: Self::Context) -> Self; fn initialize(window: &mut RunningWindow<'_>, context: Self::Context) -> Self;
@ -568,12 +567,12 @@ impl<T> kludgine::app::WindowBehavior<WindowCommand> for GooeyWindow<T>
where where
T: WindowBehavior, T: WindowBehavior,
{ {
type Context = AssertUnwindSafe<sealed::Context<T::Context>>; type Context = sealed::Context<T::Context>;
fn initialize( fn initialize(
window: kludgine::app::Window<'_, WindowCommand>, window: kludgine::app::Window<'_, WindowCommand>,
graphics: &mut kludgine::Graphics<'_>, graphics: &mut kludgine::Graphics<'_>,
AssertUnwindSafe(context): Self::Context, context: Self::Context,
) -> Self { ) -> Self {
let mut settings = context.settings.borrow_mut(); let mut settings = context.settings.borrow_mut();
let gooey = settings.gooey.clone(); let gooey = settings.gooey.clone();