diff --git a/src/widget.rs b/src/widget.rs index 73aa0fd..17c7331 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -1728,7 +1728,7 @@ impl SharedCallback { where F: FnMut(T) -> R + Send + 'static, { - Self(Arc::new(Mutex::new(Callback::new(function)))) + Self::from(Callback::new(function)) } /// Invokes the wrapped function and returns the produced value. @@ -1759,6 +1759,12 @@ impl Clone for SharedCallback { } } +impl From> for SharedCallback { + fn from(callback: Callback) -> Self { + Self(Arc::new(Mutex::new(callback))) + } +} + /// A function that can be invoked once with a parameter (`T`) and returns `R`. /// /// This type is used by widgets to signal an event that can happen only onceq. diff --git a/src/widgets/layers.rs b/src/widgets/layers.rs index ba37ba9..f666b52 100644 --- a/src/widgets/layers.rs +++ b/src/widgets/layers.rs @@ -1,7 +1,6 @@ //! Widgets that stack in the Z-direction. use std::fmt::{self, Debug}; -use std::sync::Arc; use std::time::Duration; use alot::{LotId, OrderedLots}; @@ -10,15 +9,14 @@ use easing_function::EasingFunction; use figures::units::{Lp, Px, UPx}; use figures::{IntoSigned, IntoUnsigned, Point, Rect, Size, Zero}; use intentional::Assert; -use parking_lot::Mutex; use crate::animation::{AnimationHandle, AnimationTarget, IntoAnimate, Spawn, ZeroToOne}; use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext, Trackable}; use crate::styles::components::EasingIn; use crate::value::{Destination, Dynamic, DynamicGuard, IntoValue, Source, Value}; use crate::widget::{ - Callback, MakeWidget, MountedChildren, MountedWidget, Widget, WidgetId, WidgetList, WidgetRef, - WrapperWidget, + Callback, MakeWidget, MountedChildren, MountedWidget, SharedCallback, Widget, WidgetId, + WidgetList, WidgetRef, WrapperWidget, }; use crate::widgets::container::ContainerShadow; use crate::ConstraintLimit; @@ -671,7 +669,7 @@ impl Overlayable for OverlayBuilder<'_> { } fn on_dismiss(mut self, callback: Callback) -> Self { - self.layout.on_dismiss = Some(Arc::new(Mutex::new(callback))); + self.layout.on_dismiss = Some(SharedCallback::from(callback)); self } @@ -707,13 +705,12 @@ struct OverlayLayout { positioning: Position, requires_hover: bool, layout: Option>, - on_dismiss: Option>>, + on_dismiss: Option, } impl Drop for OverlayLayout { fn drop(&mut self) { if let Some(on_dismiss) = &self.on_dismiss { - let mut on_dismiss = on_dismiss.lock(); on_dismiss.invoke(()); } } @@ -729,11 +726,7 @@ impl PartialEq for OverlayLayout { && self.positioning == other.positioning && self.requires_hover == other.requires_hover && self.layout == other.layout - && match (&self.on_dismiss, &other.on_dismiss) { - (Some(this), Some(other)) => Arc::ptr_eq(this, other), - (None, None) => true, - _ => false, - } + && self.on_dismiss == other.on_dismiss } } diff --git a/src/widgets/menu.rs b/src/widgets/menu.rs index 0a2340c..2cdc1cf 100644 --- a/src/widgets/menu.rs +++ b/src/widgets/menu.rs @@ -9,7 +9,6 @@ use figures::units::{Lp, Px, UPx}; use figures::{Angle, IntoSigned, Point, Rect, Round, ScreenScale, Size, Zero}; use kludgine::shapes::{PathBuilder, Shape, StrokeOptions}; use kludgine::DrawableExt; -use parking_lot::Mutex; use self::sealed::{SharedMenuState, SubmenuFactory}; use super::button::{ButtonColors, ButtonKind, VisualState}; @@ -25,8 +24,8 @@ use crate::styles::components::{ use crate::styles::Styles; use crate::value::{Dynamic, IntoValue, Source, Value}; use crate::widget::{ - Callback, EventHandling, MakeWidget, MakeWidgetWithTag, Widget, WidgetId, WidgetInstance, - WidgetRef, WidgetTag, HANDLED, + Callback, EventHandling, MakeWidget, MakeWidgetWithTag, SharedCallback, Widget, WidgetId, + WidgetInstance, WidgetRef, WidgetTag, HANDLED, }; use crate::ConstraintLimit; @@ -78,7 +77,7 @@ where { Menu { items: self.items, - on_click: MenuHandler(Arc::new(Mutex::new(Callback::new(selected)))), + on_click: MenuHandler(SharedCallback::new(selected)), } } } @@ -450,7 +449,7 @@ where /// A handler for a selected [`MenuItem`]. #[derive(Debug, Clone)] -pub struct MenuHandler(Arc>>); +pub struct MenuHandler(SharedCallback); #[derive(Debug)] struct OpenMenu { @@ -759,7 +758,7 @@ where let ItemKind::Item(item) = &self.items[index].item else { return; }; - self.on_click.0.lock().invoke(item.value.clone()); + self.on_click.0.invoke(item.value.clone()); let mut shared = self.shared.lock(); for handle in shared.open_menus.drain() { handle.dismiss(); diff --git a/src/window.rs b/src/window.rs index bfcf19c..0b1f1d5 100644 --- a/src/window.rs +++ b/src/window.rs @@ -61,7 +61,7 @@ use crate::value::{ Destination, Dynamic, DynamicReader, IntoDynamic, IntoValue, Source, Tracked, Value, }; use crate::widget::{ - Callback, EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, WidgetId, + EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, SharedCallback, WidgetId, WidgetInstance, HANDLED, IGNORED, }; use crate::window::sealed::WindowCommand; @@ -287,7 +287,7 @@ pub struct RunningWindow { focused: Dynamic, occluded: Dynamic, inner_size: Dynamic>, - close_requested: Option>>>, + close_requested: Option>, } impl RunningWindow @@ -303,7 +303,7 @@ where focused: &Dynamic, occluded: &Dynamic, inner_size: &Dynamic>, - close_requested: &Option>>>, + close_requested: &Option>, ) -> Self { Self { window, @@ -544,7 +544,7 @@ where outer_size: Option>>, inner_position: Option>>, outer_position: Option>>, - close_requested: Option>, + close_requested: Option>, icon: Option>>, modifiers: Option>, enabled_buttons: Option>, @@ -990,7 +990,7 @@ where where Function: FnMut(()) -> bool + Send + 'static, { - self.close_requested = Some(Callback::new(on_close_requested)); + self.close_requested = Some(SharedCallback::new(on_close_requested)); self } @@ -1072,7 +1072,7 @@ where cursive_font_family: this.cursive_font_family, vsync: this.vsync, multisample_count: this.multisample_count, - close_requested: this.close_requested.map(|cb| Arc::new(Mutex::new(cb))), + close_requested: this.close_requested, zoom: this.zoom.unwrap_or_else(|| Dynamic::new(Fraction::ONE)), resize_to_fit: this.resize_to_fit, content_protected: this.content_protected.unwrap_or_default(), @@ -1237,7 +1237,7 @@ struct OpenWindow { vsync: bool, dpi_scale: Dynamic, zoom: Tracked>, - close_requested: Option>>>, + close_requested: Option>, content_protected: Tracked>, cursor_hittest: Tracked>, cursor_visible: Tracked>, @@ -1269,8 +1269,8 @@ where *should_close |= behavior.close_requested(window) && window .close_requested - .as_mut() - .map_or(true, |close| close.lock().invoke(())); + .as_ref() + .map_or(true, |close| close.invoke(())); *should_close } @@ -2723,7 +2723,6 @@ pub(crate) struct CursorState { pub(crate) mod sealed { use std::cell::RefCell; use std::num::NonZeroU32; - use std::sync::Arc; use figures::units::{Px, UPx}; use figures::{Fraction, Point, Size}; @@ -2731,7 +2730,6 @@ pub(crate) mod sealed { use kludgine::app::winit::event::Modifiers; use kludgine::app::winit::window::{Fullscreen, UserAttentionType, WindowButtons, WindowLevel}; use kludgine::Color; - use parking_lot::Mutex; use super::{PendingWindow, WindowHandle}; use crate::app::Cushy; @@ -2739,7 +2737,7 @@ pub(crate) mod sealed { use crate::fonts::FontCollection; use crate::styles::{FontFamilyList, ThemePair}; use crate::value::{Dynamic, Value}; - use crate::widget::{Callback, OnceCallback}; + use crate::widget::{OnceCallback, SharedCallback}; use crate::window::{ThemeMode, WindowAttributes}; pub struct Context { @@ -2771,7 +2769,7 @@ pub(crate) mod sealed { pub vsync: bool, pub multisample_count: NonZeroU32, pub resize_to_fit: Value, - pub close_requested: Option>>>, + pub close_requested: Option>, pub content_protected: Value, pub cursor_hittest: Value, pub cursor_visible: Value,