Merge pull request #155 from ejmahler/remove-clone

Remove Clone bound on Application::Message
This commit is contained in:
Héctor Ramón 2020-01-13 20:28:21 +01:00 committed by GitHub
commit 142dc1e962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 44 additions and 26 deletions

View File

@ -171,7 +171,7 @@ where
/// ``` /// ```
pub fn map<F, B>(self, f: F) -> Element<'a, B, Renderer> pub fn map<F, B>(self, f: F) -> Element<'a, B, Renderer>
where where
Message: 'static + Clone, Message: 'static,
Renderer: 'a, Renderer: 'a,
B: 'static, B: 'static,
F: 'static + Fn(Message) -> B, F: 'static + Fn(Message) -> B,
@ -269,7 +269,6 @@ impl<'a, A, B, Renderer> Map<'a, A, B, Renderer> {
impl<'a, A, B, Renderer> Widget<B, Renderer> for Map<'a, A, B, Renderer> impl<'a, A, B, Renderer> Widget<B, Renderer> for Map<'a, A, B, Renderer>
where where
A: Clone,
Renderer: crate::Renderer, Renderer: crate::Renderer,
{ {
fn width(&self) -> Length { fn width(&self) -> Length {
@ -309,8 +308,7 @@ where
); );
original_messages original_messages
.iter() .drain(..)
.cloned()
.for_each(|message| messages.push((self.mapper)(message))); .for_each(|message| messages.push((self.mapper)(message)));
} }

View File

@ -83,7 +83,7 @@ pub trait Application: Sized {
/// The type of __messages__ your [`Application`] will produce. /// The type of __messages__ your [`Application`] will produce.
/// ///
/// [`Application`]: trait.Application.html /// [`Application`]: trait.Application.html
type Message: std::fmt::Debug + Send + Clone; type Message: std::fmt::Debug + Send;
/// Initializes the [`Application`]. /// Initializes the [`Application`].
/// ///

View File

@ -81,7 +81,7 @@ pub trait Sandbox {
/// The type of __messages__ your [`Sandbox`] will produce. /// The type of __messages__ your [`Sandbox`] will produce.
/// ///
/// [`Sandbox`]: trait.Sandbox.html /// [`Sandbox`]: trait.Sandbox.html
type Message: std::fmt::Debug + Send + Clone; type Message: std::fmt::Debug + Send;
/// Initializes the [`Sandbox`]. /// Initializes the [`Sandbox`].
/// ///

View File

@ -8,14 +8,21 @@ use std::rc::Rc;
/// ///
/// [`Application`]: trait.Application.html /// [`Application`]: trait.Application.html
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
#[derive(Clone)]
pub struct Bus<Message> { pub struct Bus<Message> {
publish: Rc<Box<dyn Fn(Message, &mut dyn dodrio::RootRender)>>, publish: Rc<Box<dyn Fn(Message, &mut dyn dodrio::RootRender)>>,
} }
impl<Message> Clone for Bus<Message> {
fn clone(&self) -> Self {
Self {
publish: Rc::clone(&self.publish),
}
}
}
impl<Message> Bus<Message> impl<Message> Bus<Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
Self { Self {

View File

@ -38,8 +38,8 @@ impl<'a, Message> Element<'a, Message> {
/// [`Element`]: struct.Element.html /// [`Element`]: struct.Element.html
pub fn map<F, B>(self, f: F) -> Element<'a, B> pub fn map<F, B>(self, f: F) -> Element<'a, B>
where where
Message: 'static + Clone, Message: 'static,
B: 'static + Clone, B: 'static,
F: 'static + Fn(Message) -> B, F: 'static + Fn(Message) -> B,
{ {
Element { Element {
@ -82,8 +82,8 @@ impl<'a, A, B> Map<'a, A, B> {
impl<'a, A, B> Widget<B> for Map<'a, A, B> impl<'a, A, B> Widget<B> for Map<'a, A, B>
where where
A: 'static + Clone, A: 'static,
B: 'static + Clone, B: 'static,
{ {
fn node<'b>( fn node<'b>(
&self, &self,

View File

@ -91,7 +91,7 @@ pub trait Application {
/// The type of __messages__ your [`Application`] will produce. /// The type of __messages__ your [`Application`] will produce.
/// ///
/// [`Application`]: trait.Application.html /// [`Application`]: trait.Application.html
type Message: Clone; type Message;
/// Initializes the [`Application`]. /// Initializes the [`Application`].
/// ///
@ -148,16 +148,26 @@ pub trait Application {
} }
} }
#[derive(Clone)]
struct Instance<Message> { struct Instance<Message> {
title: String, title: String,
ui: Rc<RefCell<Box<dyn Application<Message = Message>>>>, ui: Rc<RefCell<Box<dyn Application<Message = Message>>>>,
vdom: Rc<RefCell<Option<dodrio::VdomWeak>>>, vdom: Rc<RefCell<Option<dodrio::VdomWeak>>>,
} }
impl<Message> Clone for Instance<Message> {
fn clone(&self) -> Self {
Self {
title: self.title.clone(),
ui: Rc::clone(&self.ui),
vdom: Rc::clone(&self.vdom),
}
}
}
impl<Message> Instance<Message> impl<Message> Instance<Message>
where where
Message: 'static + Clone, Message: 'static
{ {
fn new(ui: impl Application<Message = Message> + 'static) -> Self { fn new(ui: impl Application<Message = Message> + 'static) -> Self {
Self { Self {
@ -221,7 +231,7 @@ where
impl<Message> dodrio::Render for Instance<Message> impl<Message> dodrio::Render for Instance<Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn render<'a, 'bump>( fn render<'a, 'bump>(
&'a self, &'a self,

View File

@ -1,6 +1,7 @@
use crate::{style, Bus, Color, Element, Widget}; use crate::{style, Bus, Color, Element, Widget};
use dodrio::bumpalo; use dodrio::bumpalo;
use std::rc::Rc;
/// A box that can be checked. /// A box that can be checked.
/// ///
@ -22,7 +23,7 @@ use dodrio::bumpalo;
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Checkbox<Message> { pub struct Checkbox<Message> {
is_checked: bool, is_checked: bool,
on_toggle: Box<dyn Fn(bool) -> Message>, on_toggle: Rc<dyn Fn(bool) -> Message>,
label: String, label: String,
label_color: Option<Color>, label_color: Option<Color>,
} }
@ -44,7 +45,7 @@ impl<Message> Checkbox<Message> {
{ {
Checkbox { Checkbox {
is_checked, is_checked,
on_toggle: Box::new(f), on_toggle: Rc::new(f),
label: String::from(label), label: String::from(label),
label_color: None, label_color: None,
} }
@ -61,7 +62,7 @@ impl<Message> Checkbox<Message> {
impl<Message> Widget<Message> for Checkbox<Message> impl<Message> Widget<Message> for Checkbox<Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn node<'b>( fn node<'b>(
&self, &self,
@ -74,7 +75,8 @@ where
let checkbox_label = bumpalo::format!(in bump, "{}", self.label); let checkbox_label = bumpalo::format!(in bump, "{}", self.label);
let event_bus = bus.clone(); let event_bus = bus.clone();
let msg = (self.on_toggle)(!self.is_checked); let on_toggle = self.on_toggle.clone();
let is_checked = self.is_checked;
// TODO: Complete styling // TODO: Complete styling
label(bump) label(bump)
@ -83,7 +85,8 @@ where
.attr("type", "checkbox") .attr("type", "checkbox")
.bool_attr("checked", self.is_checked) .bool_attr("checked", self.is_checked)
.on("click", move |root, vdom, _event| { .on("click", move |root, vdom, _event| {
event_bus.publish(msg.clone(), root); let msg = on_toggle(!is_checked);
event_bus.publish(msg, root);
vdom.schedule_render(); vdom.schedule_render();
}) })
@ -96,7 +99,7 @@ where
impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message> impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn from(checkbox: Checkbox<Message>) -> Element<'a, Message> { fn from(checkbox: Checkbox<Message>) -> Element<'a, Message> {
Element::new(checkbox) Element::new(checkbox)

View File

@ -134,7 +134,7 @@ where
impl<'a, Message> From<Scrollable<'a, Message>> for Element<'a, Message> impl<'a, Message> From<Scrollable<'a, Message>> for Element<'a, Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn from(scrollable: Scrollable<'a, Message>) -> Element<'a, Message> { fn from(scrollable: Scrollable<'a, Message>) -> Element<'a, Message> {
Element::new(scrollable) Element::new(scrollable)

View File

@ -82,7 +82,7 @@ impl<'a, Message> Slider<'a, Message> {
impl<'a, Message> Widget<Message> for Slider<'a, Message> impl<'a, Message> Widget<Message> for Slider<'a, Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn node<'b>( fn node<'b>(
&self, &self,
@ -130,7 +130,7 @@ where
impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message> impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message>
where where
Message: 'static + Clone, Message: 'static,
{ {
fn from(slider: Slider<'a, Message>) -> Element<'a, Message> { fn from(slider: Slider<'a, Message>) -> Element<'a, Message> {
Element::new(slider) Element::new(slider)

View File

@ -82,7 +82,7 @@ impl<'a, Message> TextInput<'a, Message> {
self.is_secure = true; self.is_secure = true;
self self
} }
/// Sets the width of the [`TextInput`]. /// Sets the width of the [`TextInput`].
/// ///
/// [`TextInput`]: struct.TextInput.html /// [`TextInput`]: struct.TextInput.html