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