Standardizing on SharedCallback

This commit is contained in:
Jonathan Johnson 2024-09-09 16:37:04 -07:00
parent c2d07344d9
commit aa7e526965
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
4 changed files with 28 additions and 32 deletions

View file

@ -1728,7 +1728,7 @@ impl<T, R> SharedCallback<T, R> {
where where
F: FnMut(T) -> R + Send + 'static, 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. /// Invokes the wrapped function and returns the produced value.
@ -1759,6 +1759,12 @@ impl<T, R> Clone for SharedCallback<T, R> {
} }
} }
impl<T, R> From<Callback<T, R>> for SharedCallback<T, R> {
fn from(callback: Callback<T, R>) -> Self {
Self(Arc::new(Mutex::new(callback)))
}
}
/// A function that can be invoked once with a parameter (`T`) and returns `R`. /// 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. /// This type is used by widgets to signal an event that can happen only onceq.

View file

@ -1,7 +1,6 @@
//! Widgets that stack in the Z-direction. //! Widgets that stack in the Z-direction.
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use alot::{LotId, OrderedLots}; use alot::{LotId, OrderedLots};
@ -10,15 +9,14 @@ use easing_function::EasingFunction;
use figures::units::{Lp, Px, UPx}; use figures::units::{Lp, Px, UPx};
use figures::{IntoSigned, IntoUnsigned, Point, Rect, Size, Zero}; use figures::{IntoSigned, IntoUnsigned, Point, Rect, Size, Zero};
use intentional::Assert; use intentional::Assert;
use parking_lot::Mutex;
use crate::animation::{AnimationHandle, AnimationTarget, IntoAnimate, Spawn, ZeroToOne}; use crate::animation::{AnimationHandle, AnimationTarget, IntoAnimate, Spawn, ZeroToOne};
use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext, Trackable}; use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext, Trackable};
use crate::styles::components::EasingIn; use crate::styles::components::EasingIn;
use crate::value::{Destination, Dynamic, DynamicGuard, IntoValue, Source, Value}; use crate::value::{Destination, Dynamic, DynamicGuard, IntoValue, Source, Value};
use crate::widget::{ use crate::widget::{
Callback, MakeWidget, MountedChildren, MountedWidget, Widget, WidgetId, WidgetList, WidgetRef, Callback, MakeWidget, MountedChildren, MountedWidget, SharedCallback, Widget, WidgetId,
WrapperWidget, WidgetList, WidgetRef, WrapperWidget,
}; };
use crate::widgets::container::ContainerShadow; use crate::widgets::container::ContainerShadow;
use crate::ConstraintLimit; use crate::ConstraintLimit;
@ -671,7 +669,7 @@ impl Overlayable for OverlayBuilder<'_> {
} }
fn on_dismiss(mut self, callback: Callback) -> Self { 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 self
} }
@ -707,13 +705,12 @@ struct OverlayLayout {
positioning: Position<Px>, positioning: Position<Px>,
requires_hover: bool, requires_hover: bool,
layout: Option<Rect<Px>>, layout: Option<Rect<Px>>,
on_dismiss: Option<Arc<Mutex<Callback>>>, on_dismiss: Option<SharedCallback>,
} }
impl Drop for OverlayLayout { impl Drop for OverlayLayout {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(on_dismiss) = &self.on_dismiss { if let Some(on_dismiss) = &self.on_dismiss {
let mut on_dismiss = on_dismiss.lock();
on_dismiss.invoke(()); on_dismiss.invoke(());
} }
} }
@ -729,11 +726,7 @@ impl PartialEq for OverlayLayout {
&& self.positioning == other.positioning && self.positioning == other.positioning
&& self.requires_hover == other.requires_hover && self.requires_hover == other.requires_hover
&& self.layout == other.layout && self.layout == other.layout
&& match (&self.on_dismiss, &other.on_dismiss) { && self.on_dismiss == other.on_dismiss
(Some(this), Some(other)) => Arc::ptr_eq(this, other),
(None, None) => true,
_ => false,
}
} }
} }

View file

@ -9,7 +9,6 @@ use figures::units::{Lp, Px, UPx};
use figures::{Angle, IntoSigned, Point, Rect, Round, ScreenScale, Size, Zero}; use figures::{Angle, IntoSigned, Point, Rect, Round, ScreenScale, Size, Zero};
use kludgine::shapes::{PathBuilder, Shape, StrokeOptions}; use kludgine::shapes::{PathBuilder, Shape, StrokeOptions};
use kludgine::DrawableExt; use kludgine::DrawableExt;
use parking_lot::Mutex;
use self::sealed::{SharedMenuState, SubmenuFactory}; use self::sealed::{SharedMenuState, SubmenuFactory};
use super::button::{ButtonColors, ButtonKind, VisualState}; use super::button::{ButtonColors, ButtonKind, VisualState};
@ -25,8 +24,8 @@ use crate::styles::components::{
use crate::styles::Styles; use crate::styles::Styles;
use crate::value::{Dynamic, IntoValue, Source, Value}; use crate::value::{Dynamic, IntoValue, Source, Value};
use crate::widget::{ use crate::widget::{
Callback, EventHandling, MakeWidget, MakeWidgetWithTag, Widget, WidgetId, WidgetInstance, Callback, EventHandling, MakeWidget, MakeWidgetWithTag, SharedCallback, Widget, WidgetId,
WidgetRef, WidgetTag, HANDLED, WidgetInstance, WidgetRef, WidgetTag, HANDLED,
}; };
use crate::ConstraintLimit; use crate::ConstraintLimit;
@ -78,7 +77,7 @@ where
{ {
Menu { Menu {
items: self.items, 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<T>`]. /// A handler for a selected [`MenuItem<T>`].
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MenuHandler<T>(Arc<Mutex<Callback<T>>>); pub struct MenuHandler<T>(SharedCallback<T>);
#[derive(Debug)] #[derive(Debug)]
struct OpenMenu<T> { struct OpenMenu<T> {
@ -759,7 +758,7 @@ where
let ItemKind::Item(item) = &self.items[index].item else { let ItemKind::Item(item) = &self.items[index].item else {
return; return;
}; };
self.on_click.0.lock().invoke(item.value.clone()); self.on_click.0.invoke(item.value.clone());
let mut shared = self.shared.lock(); let mut shared = self.shared.lock();
for handle in shared.open_menus.drain() { for handle in shared.open_menus.drain() {
handle.dismiss(); handle.dismiss();

View file

@ -61,7 +61,7 @@ use crate::value::{
Destination, Dynamic, DynamicReader, IntoDynamic, IntoValue, Source, Tracked, Value, Destination, Dynamic, DynamicReader, IntoDynamic, IntoValue, Source, Tracked, Value,
}; };
use crate::widget::{ use crate::widget::{
Callback, EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, WidgetId, EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, SharedCallback, WidgetId,
WidgetInstance, HANDLED, IGNORED, WidgetInstance, HANDLED, IGNORED,
}; };
use crate::window::sealed::WindowCommand; use crate::window::sealed::WindowCommand;
@ -287,7 +287,7 @@ pub struct RunningWindow<W> {
focused: Dynamic<bool>, focused: Dynamic<bool>,
occluded: Dynamic<bool>, occluded: Dynamic<bool>,
inner_size: Dynamic<Size<UPx>>, inner_size: Dynamic<Size<UPx>>,
close_requested: Option<Arc<Mutex<Callback<(), bool>>>>, close_requested: Option<SharedCallback<(), bool>>,
} }
impl<W> RunningWindow<W> impl<W> RunningWindow<W>
@ -303,7 +303,7 @@ where
focused: &Dynamic<bool>, focused: &Dynamic<bool>,
occluded: &Dynamic<bool>, occluded: &Dynamic<bool>,
inner_size: &Dynamic<Size<UPx>>, inner_size: &Dynamic<Size<UPx>>,
close_requested: &Option<Arc<Mutex<Callback<(), bool>>>>, close_requested: &Option<SharedCallback<(), bool>>,
) -> Self { ) -> Self {
Self { Self {
window, window,
@ -544,7 +544,7 @@ where
outer_size: Option<Dynamic<Size<UPx>>>, outer_size: Option<Dynamic<Size<UPx>>>,
inner_position: Option<Dynamic<Point<Px>>>, inner_position: Option<Dynamic<Point<Px>>>,
outer_position: Option<Dynamic<Point<Px>>>, outer_position: Option<Dynamic<Point<Px>>>,
close_requested: Option<Callback<(), bool>>, close_requested: Option<SharedCallback<(), bool>>,
icon: Option<Value<Option<RgbaImage>>>, icon: Option<Value<Option<RgbaImage>>>,
modifiers: Option<Dynamic<Modifiers>>, modifiers: Option<Dynamic<Modifiers>>,
enabled_buttons: Option<Value<WindowButtons>>, enabled_buttons: Option<Value<WindowButtons>>,
@ -990,7 +990,7 @@ where
where where
Function: FnMut(()) -> bool + Send + 'static, Function: FnMut(()) -> bool + Send + 'static,
{ {
self.close_requested = Some(Callback::new(on_close_requested)); self.close_requested = Some(SharedCallback::new(on_close_requested));
self self
} }
@ -1072,7 +1072,7 @@ where
cursive_font_family: this.cursive_font_family, cursive_font_family: this.cursive_font_family,
vsync: this.vsync, vsync: this.vsync,
multisample_count: this.multisample_count, 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)), zoom: this.zoom.unwrap_or_else(|| Dynamic::new(Fraction::ONE)),
resize_to_fit: this.resize_to_fit, resize_to_fit: this.resize_to_fit,
content_protected: this.content_protected.unwrap_or_default(), content_protected: this.content_protected.unwrap_or_default(),
@ -1237,7 +1237,7 @@ struct OpenWindow<T> {
vsync: bool, vsync: bool,
dpi_scale: Dynamic<Fraction>, dpi_scale: Dynamic<Fraction>,
zoom: Tracked<Dynamic<Fraction>>, zoom: Tracked<Dynamic<Fraction>>,
close_requested: Option<Arc<Mutex<Callback<(), bool>>>>, close_requested: Option<SharedCallback<(), bool>>,
content_protected: Tracked<Value<bool>>, content_protected: Tracked<Value<bool>>,
cursor_hittest: Tracked<Value<bool>>, cursor_hittest: Tracked<Value<bool>>,
cursor_visible: Tracked<Value<bool>>, cursor_visible: Tracked<Value<bool>>,
@ -1269,8 +1269,8 @@ where
*should_close |= behavior.close_requested(window) *should_close |= behavior.close_requested(window)
&& window && window
.close_requested .close_requested
.as_mut() .as_ref()
.map_or(true, |close| close.lock().invoke(())); .map_or(true, |close| close.invoke(()));
*should_close *should_close
} }
@ -2723,7 +2723,6 @@ pub(crate) struct CursorState {
pub(crate) mod sealed { pub(crate) mod sealed {
use std::cell::RefCell; use std::cell::RefCell;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::sync::Arc;
use figures::units::{Px, UPx}; use figures::units::{Px, UPx};
use figures::{Fraction, Point, Size}; use figures::{Fraction, Point, Size};
@ -2731,7 +2730,6 @@ pub(crate) mod sealed {
use kludgine::app::winit::event::Modifiers; use kludgine::app::winit::event::Modifiers;
use kludgine::app::winit::window::{Fullscreen, UserAttentionType, WindowButtons, WindowLevel}; use kludgine::app::winit::window::{Fullscreen, UserAttentionType, WindowButtons, WindowLevel};
use kludgine::Color; use kludgine::Color;
use parking_lot::Mutex;
use super::{PendingWindow, WindowHandle}; use super::{PendingWindow, WindowHandle};
use crate::app::Cushy; use crate::app::Cushy;
@ -2739,7 +2737,7 @@ pub(crate) mod sealed {
use crate::fonts::FontCollection; use crate::fonts::FontCollection;
use crate::styles::{FontFamilyList, ThemePair}; use crate::styles::{FontFamilyList, ThemePair};
use crate::value::{Dynamic, Value}; use crate::value::{Dynamic, Value};
use crate::widget::{Callback, OnceCallback}; use crate::widget::{OnceCallback, SharedCallback};
use crate::window::{ThemeMode, WindowAttributes}; use crate::window::{ThemeMode, WindowAttributes};
pub struct Context<C> { pub struct Context<C> {
@ -2771,7 +2769,7 @@ pub(crate) mod sealed {
pub vsync: bool, pub vsync: bool,
pub multisample_count: NonZeroU32, pub multisample_count: NonZeroU32,
pub resize_to_fit: Value<bool>, pub resize_to_fit: Value<bool>,
pub close_requested: Option<Arc<Mutex<Callback<(), bool>>>>, pub close_requested: Option<SharedCallback<(), bool>>,
pub content_protected: Value<bool>, pub content_protected: Value<bool>,
pub cursor_hittest: Value<bool>, pub cursor_hittest: Value<bool>,
pub cursor_visible: Value<bool>, pub cursor_visible: Value<bool>,