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
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<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`.
///
/// 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.
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<Px>,
requires_hover: bool,
layout: Option<Rect<Px>>,
on_dismiss: Option<Arc<Mutex<Callback>>>,
on_dismiss: Option<SharedCallback>,
}
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
}
}

View file

@ -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<T>`].
#[derive(Debug, Clone)]
pub struct MenuHandler<T>(Arc<Mutex<Callback<T>>>);
pub struct MenuHandler<T>(SharedCallback<T>);
#[derive(Debug)]
struct OpenMenu<T> {
@ -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();

View file

@ -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<W> {
focused: Dynamic<bool>,
occluded: Dynamic<bool>,
inner_size: Dynamic<Size<UPx>>,
close_requested: Option<Arc<Mutex<Callback<(), bool>>>>,
close_requested: Option<SharedCallback<(), bool>>,
}
impl<W> RunningWindow<W>
@ -303,7 +303,7 @@ where
focused: &Dynamic<bool>,
occluded: &Dynamic<bool>,
inner_size: &Dynamic<Size<UPx>>,
close_requested: &Option<Arc<Mutex<Callback<(), bool>>>>,
close_requested: &Option<SharedCallback<(), bool>>,
) -> Self {
Self {
window,
@ -544,7 +544,7 @@ where
outer_size: Option<Dynamic<Size<UPx>>>,
inner_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>>>,
modifiers: Option<Dynamic<Modifiers>>,
enabled_buttons: Option<Value<WindowButtons>>,
@ -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<T> {
vsync: bool,
dpi_scale: Dynamic<Fraction>,
zoom: Tracked<Dynamic<Fraction>>,
close_requested: Option<Arc<Mutex<Callback<(), bool>>>>,
close_requested: Option<SharedCallback<(), bool>>,
content_protected: Tracked<Value<bool>>,
cursor_hittest: Tracked<Value<bool>>,
cursor_visible: Tracked<Value<bool>>,
@ -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<C> {
@ -2771,7 +2769,7 @@ pub(crate) mod sealed {
pub vsync: bool,
pub multisample_count: NonZeroU32,
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 cursor_hittest: Value<bool>,
pub cursor_visible: Value<bool>,