Replace event::AnyCb with non-boxed &dyn FnMut

This commit is contained in:
Alexandre Bury 2019-09-06 16:02:20 -07:00
parent 1fcb9db79c
commit 769ab8bf9b
10 changed files with 34 additions and 28 deletions

View File

@ -1,5 +1,17 @@
# Changelog # Changelog
## 0.14.0 (Next version)
### Breaking changes
- `cursive::event::AnyCb` changed from `Box<...>` to `&mut ...`, so users of
`View::call_on_any` no longer need to box their closures.
- Remove `BoxView::squishable`
### Bugfixes
- Fixed layout for `BoxView` with some size constraints.
## 0.13.0 ## 0.13.0
### Breaking changes ### Breaking changes

View File

@ -22,14 +22,20 @@ use std::rc::Rc;
/// Callback is a function that can be triggered by an event. /// Callback is a function that can be triggered by an event.
/// It has a mutable access to the cursive root. /// It has a mutable access to the cursive root.
///
/// It is meant to be stored in views.
#[derive(Clone)] #[derive(Clone)]
pub struct Callback(Rc<Box<dyn Fn(&mut Cursive)>>); pub struct Callback(Rc<Box<dyn Fn(&mut Cursive)>>);
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible // TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible
/// A boxed callback that can be run on `&mut Any`. /// A callback that can be run on `&mut Any`.
pub type AnyCb<'a> = Box<dyn FnMut(&mut dyn Any) + 'a>; ///
/// It is meant to be used as parameter in `View::call_on_any`, and not much else.
pub type AnyCb<'a> = &'a mut dyn FnMut(&mut dyn Any);
/// A trigger that only selects some types of events. /// A trigger that only selects some types of events.
///
/// It is meant to be stored in views.
pub struct EventTrigger(Box<dyn Fn(&Event) -> bool>); pub struct EventTrigger(Box<dyn Fn(&Event) -> bool>);
impl EventTrigger { impl EventTrigger {

View File

@ -60,7 +60,7 @@ impl<T: View> Finder for T {
let result_ref = &mut result; let result_ref = &mut result;
let mut callback = Some(callback); let mut callback = Some(callback);
let callback = |v: &mut dyn Any| { let mut callback = |v: &mut dyn Any| {
if let Some(callback) = callback.take() { if let Some(callback) = callback.take() {
if v.is::<V>() { if v.is::<V>() {
*result_ref = *result_ref =
@ -72,7 +72,7 @@ impl<T: View> Finder for T {
} }
} }
}; };
self.call_on_any(sel, Box::new(callback)); self.call_on_any(sel, &mut callback);
} }
result result
} }

View File

@ -4,7 +4,6 @@ use crate::rect::Rect;
use crate::vec::Vec2; use crate::vec::Vec2;
use crate::view::{Selector, View}; use crate::view::{Selector, View};
use crate::Printer; use crate::Printer;
use std::any::Any;
/// Generic wrapper around a view. /// Generic wrapper around a view.
/// ///
@ -129,7 +128,7 @@ impl<T: ViewWrapper> View for T {
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
callback: Box<dyn FnMut(&mut dyn Any) + 'a>, callback: AnyCb<'a>,
) { ) {
self.wrap_call_on_any(selector, callback) self.wrap_call_on_any(selector, callback)
} }

View File

@ -1,7 +1,6 @@
use crate::printer::Printer; use crate::printer::Printer;
use crate::vec::Vec2; use crate::vec::Vec2;
use crate::view::{SizeConstraint, View, ViewWrapper}; use crate::view::{SizeConstraint, View, ViewWrapper};
use crate::With;
use crate::XY; use crate::XY;
/// Wrapper around another view, with a controlled size. /// Wrapper around another view, with a controlled size.

View File

@ -1,9 +1,8 @@
use crate::event::AnyCb;
use crate::vec::Vec2; use crate::vec::Vec2;
use crate::view::{Selector, View, ViewWrapper}; use crate::view::{Selector, View, ViewWrapper};
use crate::With; use crate::With;
use std::any::Any;
/// Wrapper around another view that can be hidden at will. /// Wrapper around another view that can be hidden at will.
/// ///
/// By default, it simply forwards all calls to the inner view. /// By default, it simply forwards all calls to the inner view.
@ -93,7 +92,7 @@ impl<V: View> ViewWrapper for HideableView<V> {
fn wrap_call_on_any<'a>( fn wrap_call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
callback: Box<dyn FnMut(&mut dyn Any) + 'a>, callback: AnyCb<'a>,
) { ) {
// We always run callbacks, even when invisible. // We always run callbacks, even when invisible.
self.view.call_on_any(selector, callback) self.view.call_on_any(selector, callback)

View File

@ -1,6 +1,6 @@
use crate::event::AnyCb;
use crate::view::{Selector, View, ViewWrapper}; use crate::view::{Selector, View, ViewWrapper};
use owning_ref::{OwningHandle, RcRef}; use owning_ref::{OwningHandle, RcRef};
use std::any::Any;
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
use std::ops::DerefMut; use std::ops::DerefMut;
use std::rc::Rc; use std::rc::Rc;
@ -41,9 +41,6 @@ impl<V: View> IdView<V> {
} }
} }
// Shortcut for a boxed callback (for the wrap_call_on_any method).
type BoxedCallback<'a> = Box<dyn for<'b> FnMut(&'b mut dyn Any) + 'a>;
impl<T: View + 'static> ViewWrapper for IdView<T> { impl<T: View + 'static> ViewWrapper for IdView<T> {
type V = T; type V = T;
@ -79,7 +76,7 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
fn wrap_call_on_any<'a>( fn wrap_call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
mut callback: BoxedCallback<'a>, callback: AnyCb<'a>,
) { ) {
match selector { match selector {
&Selector::Id(id) if id == self.id => callback(self), &Selector::Id(id) if id == self.id => callback(self),

View File

@ -639,12 +639,10 @@ impl View for LinearLayout {
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
mut callback: AnyCb<'a>, callback: AnyCb<'a>,
) { ) {
for child in &mut self.children { for child in &mut self.children {
child child.view.call_on_any(selector, callback);
.view
.call_on_any(selector, Box::new(|any| callback(any)));
} }
} }

View File

@ -396,10 +396,10 @@ impl View for ListView {
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
mut callback: AnyCb<'a>, callback: AnyCb<'a>,
) { ) {
for view in self.children.iter_mut().filter_map(ListChild::view) { for view in self.children.iter_mut().filter_map(ListChild::view) {
view.call_on_any(selector, Box::new(|any| callback(any))); view.call_on_any(selector, callback);
} }
} }

View File

@ -324,9 +324,7 @@ impl StackView {
for (i, child) in self.layers.iter_mut().enumerate() { for (i, child) in self.layers.iter_mut().enumerate() {
let mut found = false; let mut found = false;
child child.view.call_on_any(&selector, &mut |_| found = true);
.view
.call_on_any(&selector, Box::new(|_| found = true));
if found { if found {
return Some(LayerPosition::FromBack(i)); return Some(LayerPosition::FromBack(i));
} }
@ -668,12 +666,10 @@ impl View for StackView {
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, &mut self,
selector: &Selector<'_>, selector: &Selector<'_>,
mut callback: AnyCb<'a>, callback: AnyCb<'a>,
) { ) {
for layer in &mut self.layers { for layer in &mut self.layers {
layer layer.view.call_on_any(selector, callback);
.view
.call_on_any(selector, Box::new(|any| callback(any)));
} }
} }