mirror of
https://github.com/danbulant/cushy
synced 2026-05-24 12:28:23 +00:00
Callback can now return a result
This commit is contained in:
parent
304032f1b0
commit
5b94d37b6f
4 changed files with 29 additions and 35 deletions
|
|
@ -31,12 +31,7 @@ impl<T> Dynamic<T> {
|
|||
}
|
||||
|
||||
pub fn map_mut<R>(&self, map: impl FnOnce(&mut T) -> R) -> R {
|
||||
let mut state = self.state();
|
||||
state.wrapped.generation = state.wrapped.generation.wrapping_add(1);
|
||||
let result = map(&mut state.wrapped.value);
|
||||
drop(state);
|
||||
self.0.sync.notify_all();
|
||||
result
|
||||
self.0.map_mut(map)
|
||||
}
|
||||
|
||||
pub fn for_each<F>(&self, mut map: F)
|
||||
|
|
@ -72,7 +67,7 @@ impl<T> Dynamic<T> {
|
|||
|
||||
#[must_use]
|
||||
pub fn replace(&self, new_value: T) -> T {
|
||||
self.0.replace(new_value).value
|
||||
self.0.map_mut(|value| std::mem::replace(value, new_value))
|
||||
}
|
||||
|
||||
pub fn set(&self, new_value: T) {
|
||||
|
|
@ -150,18 +145,13 @@ impl<T> DynamicData<T> {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn replace(&self, new_value: T) -> GenerationalValue<T> {
|
||||
pub fn map_mut<R>(&self, map: impl FnOnce(&mut T) -> R) -> R {
|
||||
let mut state = self.state();
|
||||
let old = {
|
||||
let state = &mut *state;
|
||||
let generation = state.wrapped.generation.wrapping_add(1);
|
||||
let old = std::mem::replace(
|
||||
&mut state.wrapped,
|
||||
GenerationalValue {
|
||||
value: new_value,
|
||||
generation,
|
||||
},
|
||||
);
|
||||
let result = map(&mut state.wrapped.value);
|
||||
state.wrapped.generation = generation;
|
||||
|
||||
for callback in &mut state.callbacks {
|
||||
callback.update(&state.wrapped);
|
||||
|
|
@ -169,7 +159,7 @@ impl<T> DynamicData<T> {
|
|||
for window in state.windows.drain(..) {
|
||||
let _result = window.send(WindowCommand::Redraw);
|
||||
}
|
||||
old
|
||||
result
|
||||
};
|
||||
drop(state);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use kludgine::app::winit::event::{
|
|||
use kludgine::figures::units::{Px, UPx};
|
||||
use kludgine::figures::{Point, Rect, Size};
|
||||
|
||||
use crate::context::{EventContext, GraphicsContext};
|
||||
use crate::context::{EventContext, GraphicsContext, WidgetContext};
|
||||
use crate::dynamic::Dynamic;
|
||||
use crate::styles::{Component, Group, Styles};
|
||||
use crate::tree::{Tree, WidgetId};
|
||||
|
|
@ -246,6 +246,12 @@ impl<T> Value<T> {
|
|||
Value::Dynamic(value) => Some(value.generation()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redraw_when_changed(&self, context: &WidgetContext<'_, '_>) {
|
||||
if let Value::Dynamic(dynamic) = self {
|
||||
context.redraw_when_changed(dynamic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoValue<T> {
|
||||
|
|
@ -276,9 +282,9 @@ impl<T> IntoValue<T> for Value<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Callback<T>(Box<dyn CallbackFunction<T>>);
|
||||
pub struct Callback<T = (), R = ()>(Box<dyn CallbackFunction<T, R>>);
|
||||
|
||||
impl<T> Debug for Callback<T> {
|
||||
impl<T, R> Debug for Callback<T, R> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("Callback")
|
||||
.field(&(self as *const Self))
|
||||
|
|
@ -286,28 +292,29 @@ impl<T> Debug for Callback<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Callback<T> {
|
||||
impl<T, R> Callback<T, R> {
|
||||
pub fn new<F>(function: F) -> Self
|
||||
where
|
||||
F: FnMut(T) + Send + UnwindSafe + 'static,
|
||||
F: FnMut(T) -> R + Send + UnwindSafe + 'static,
|
||||
{
|
||||
Self(Box::new(function))
|
||||
}
|
||||
|
||||
pub fn invoke(&mut self, value: T) {
|
||||
self.0.invoke(value);
|
||||
pub fn invoke(&mut self, value: T) -> R {
|
||||
self.0.invoke(value)
|
||||
}
|
||||
}
|
||||
|
||||
trait CallbackFunction<T>: Send + UnwindSafe {
|
||||
fn invoke(&mut self, value: T);
|
||||
trait CallbackFunction<T, R>: Send + UnwindSafe {
|
||||
fn invoke(&mut self, value: T) -> R;
|
||||
}
|
||||
impl<T, F> CallbackFunction<T> for F
|
||||
|
||||
impl<T, R, F> CallbackFunction<T, R> for F
|
||||
where
|
||||
F: FnMut(T) + Send + UnwindSafe,
|
||||
F: FnMut(T) -> R + Send + UnwindSafe,
|
||||
{
|
||||
fn invoke(&mut self, value: T) {
|
||||
self(value);
|
||||
fn invoke(&mut self, value: T) -> R {
|
||||
self(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,9 +50,7 @@ impl Button {
|
|||
impl Widget for Button {
|
||||
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
||||
let center = Point::from(context.graphics.size()) / 2;
|
||||
if let Value::Dynamic(label) = &self.label {
|
||||
context.redraw_when_changed(label);
|
||||
}
|
||||
self.label.redraw_when_changed(context);
|
||||
|
||||
let styles = context.query_style(&[
|
||||
&TextColor,
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@ impl Label {
|
|||
|
||||
impl Widget for Label {
|
||||
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
||||
self.contents.redraw_when_changed(context);
|
||||
|
||||
let center = Point::from(context.graphics.size()) / 2;
|
||||
if let Value::Dynamic(contents) = &mut self.contents {
|
||||
context.redraw_when_changed(contents);
|
||||
}
|
||||
let styles = context.query_style(&[&TextColor]);
|
||||
let width = context.graphics.size().width;
|
||||
self.contents.map(|contents| {
|
||||
|
|
|
|||
Loading…
Reference in a new issue