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
## 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
### Breaking changes

View File

@ -22,14 +22,20 @@ use std::rc::Rc;
/// Callback is a function that can be triggered by an event.
/// It has a mutable access to the cursive root.
///
/// It is meant to be stored in views.
#[derive(Clone)]
pub struct Callback(Rc<Box<dyn Fn(&mut Cursive)>>);
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible
/// A boxed callback that can be run on `&mut Any`.
pub type AnyCb<'a> = Box<dyn FnMut(&mut dyn Any) + 'a>;
/// A callback that can be run on `&mut Any`.
///
/// 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.
///
/// It is meant to be stored in views.
pub struct EventTrigger(Box<dyn Fn(&Event) -> bool>);
impl EventTrigger {

View File

@ -60,7 +60,7 @@ impl<T: View> Finder for T {
let result_ref = &mut result;
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 v.is::<V>() {
*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
}

View File

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

View File

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

View File

@ -1,9 +1,8 @@
use crate::event::AnyCb;
use crate::vec::Vec2;
use crate::view::{Selector, View, ViewWrapper};
use crate::With;
use std::any::Any;
/// Wrapper around another view that can be hidden at will.
///
/// 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>(
&mut self,
selector: &Selector<'_>,
callback: Box<dyn FnMut(&mut dyn Any) + 'a>,
callback: AnyCb<'a>,
) {
// We always run callbacks, even when invisible.
self.view.call_on_any(selector, callback)

View File

@ -1,6 +1,6 @@
use crate::event::AnyCb;
use crate::view::{Selector, View, ViewWrapper};
use owning_ref::{OwningHandle, RcRef};
use std::any::Any;
use std::cell::{RefCell, RefMut};
use std::ops::DerefMut;
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> {
type V = T;
@ -79,7 +76,7 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
fn wrap_call_on_any<'a>(
&mut self,
selector: &Selector<'_>,
mut callback: BoxedCallback<'a>,
callback: AnyCb<'a>,
) {
match selector {
&Selector::Id(id) if id == self.id => callback(self),

View File

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

View File

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