Skip to content

Commit

Permalink
Refactor HiddenScope to clean up code (yewstack#778)
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry authored and llebout committed Jan 20, 2020
1 parent 7055c18 commit 6030b05
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/html/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ mod listener;
mod scope;

pub use listener::*;
pub(crate) use scope::ComponentUpdate;
pub use scope::Scope;
pub(crate) use scope::{ComponentUpdate, HiddenScope};

use crate::callback::Callback;
use crate::virtual_dom::{VChild, VList, VNode};
Expand Down
29 changes: 29 additions & 0 deletions src/html/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,32 @@ where
});
}
}

struct Hidden;

pub(crate) struct HiddenScope {
type_id: TypeId,
scope: *mut Hidden,
}

impl<COMP: Component> From<Scope<COMP>> for HiddenScope {
fn from(scope: Scope<COMP>) -> Self {
HiddenScope {
type_id: TypeId::of::<COMP>(),
scope: Box::into_raw(Box::new(scope)) as *mut Hidden,
}
}
}

impl<COMP: Component> Into<Scope<COMP>> for HiddenScope {
fn into(self: HiddenScope) -> Scope<COMP> {
if self.type_id != TypeId::of::<COMP>() {
panic!("encountered unespected component type");
}

unsafe {
let raw: *mut Scope<COMP> = self.scope as *mut Scope<COMP>;
*Box::from_raw(raw)
}
}
}
38 changes: 12 additions & 26 deletions src/virtual_dom/vcomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@
use super::{VDiff, VNode};
use crate::callback::Callback;
use crate::html::{Component, ComponentUpdate, NodeRef, Scope};
use crate::html::{Component, ComponentUpdate, HiddenScope, NodeRef, Scope};
use std::any::TypeId;
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
use stdweb::web::{document, Element, INode, Node, TextNode};

struct Hidden;

type HiddenScope = *mut Hidden;

/// The method generates an instance of a component.
type Generator<PARENT> = dyn FnOnce(GeneratorType, Scope<PARENT>) -> Mounted;

/// Components can be generated by mounting or by overwriting an old component.
enum GeneratorType {
Mount(Element, TextNode),
Overwrite(TypeId, HiddenScope),
Overwrite(HiddenScope),
}

/// A reference to the parent's scope which will be used later to send messages.
Expand Down Expand Up @@ -109,25 +105,17 @@ impl<PARENT: Component> VComp<PARENT> {

Mounted {
node_ref,
scope: Box::into_raw(Box::new(scope.clone())) as *mut Hidden,
scope: scope.clone().into(),
destroyer: Box::new(move || scope.destroy()),
}
}
GeneratorType::Overwrite(type_id, scope) => {
if type_id != TypeId::of::<SELF>() {
panic!("tried to overwrite a different type of component");
}

let mut scope = unsafe {
let raw: *mut Scope<SELF> = scope as *mut Scope<SELF>;
*Box::from_raw(raw)
};

GeneratorType::Overwrite(hidden_scope) => {
let mut scope: Scope<SELF> = hidden_scope.into();
scope.update(ComponentUpdate::Properties(props));

Mounted {
node_ref,
scope: Box::into_raw(Box::new(scope.clone())) as *mut Hidden,
scope: scope.clone().into(),
destroyer: Box::new(move || scope.destroy()),
}
}
Expand Down Expand Up @@ -220,13 +208,13 @@ impl<PARENT: Component> Unmounted<PARENT> {
}

/// Overwrite an existing virtual component using a generator.
fn replace(self, type_id: TypeId, old: Mounted, parent_scope: Scope<PARENT>) -> Mounted {
(self.generator)(GeneratorType::Overwrite(type_id, old.scope), parent_scope)
fn replace(self, old: Mounted, parent_scope: Scope<PARENT>) -> Mounted {
(self.generator)(GeneratorType::Overwrite(old.scope), parent_scope)
}
}

enum Reform {
Keep(TypeId, Mounted),
Keep(Mounted),
Before(Option<Node>),
}

Expand Down Expand Up @@ -267,9 +255,7 @@ where
// old Component but update the properties.
if self.type_id == vcomp.type_id {
match vcomp.state.replace(MountState::Overwritten) {
MountState::Mounted(mounted) => {
Reform::Keep(vcomp.type_id, mounted)
}
MountState::Mounted(mounted) => Reform::Keep(mounted),
_ => Reform::Before(None),
}
} else {
Expand All @@ -285,9 +271,9 @@ where
};

let mounted = match reform {
Reform::Keep(type_id, mounted) => {
Reform::Keep(mounted) => {
// Send properties update when the component is already rendered.
this.replace(type_id, mounted, parent_scope.clone())
this.replace(mounted, parent_scope.clone())
}
Reform::Before(before) => {
// Temporary node which will be replaced by a component's root node.
Expand Down

0 comments on commit 6030b05

Please sign in to comment.