wip: more clean up

This commit is contained in:
Jonathan Kelley committed 2021-09-13 01:14:09 -04:00
1 parent 8b3ac0b57c
commit 5a09ec1610
5 files changed
+48 -20

No files matched your search

+6 -11
View File
@@ -113,7 +113,7 @@ pub(crate) struct DiffMachine<'bump> {
} }
pub(crate) struct DiffCfg { pub(crate) struct DiffCfg {
force_diff: bool, pub force_diff: bool,
} }
impl Default for DiffCfg { impl Default for DiffCfg {
fn default() -> Self { fn default() -> Self {
@@ -172,6 +172,7 @@ impl<'bump> DiffMachine<'bump> {
if let Some(component) = self.vdom.get_scope_mut(id) { if let Some(component) = self.vdom.get_scope_mut(id) {
let (old, new) = (component.frames.wip_head(), component.frames.fin_head()); let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
self.stack.push(DiffInstruction::Diff { new, old }); self.stack.push(DiffInstruction::Diff { new, old });
self.work(|| false);
} }
} }
@@ -535,17 +536,11 @@ impl<'bump> DiffMachine<'bump> {
scope.update_scope_dependencies(new.caller.clone(), ScopeChildren(new.children)); scope.update_scope_dependencies(new.caller.clone(), ScopeChildren(new.children));
// React doesn't automatically memoize, but we do. // React doesn't automatically memoize, but we do.
let compare = old.comparator.unwrap(); let props_are_the_same = old.comparator.unwrap();
match compare(new) { if self.cfg.force_diff || !props_are_the_same(new) {
true => { if scope.run_scope(self.vdom) {
// the props are the same... do nothing self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
}
false => {
// the props are different...
if scope.run_scope(self.vdom) {
self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
}
} }
} }
+2
View File
@@ -488,6 +488,8 @@ impl<'a> NodeFactory<'a> {
std::mem::drop(b); std::mem::drop(b);
has_dropped = true; has_dropped = true;
} else {
panic!("Drop props called twice - this is an internal failure of Dioxus");
} }
} }
}); });
-4
View File
@@ -566,10 +566,6 @@ impl Scheduler {
// EventPriority::Low => self.low_priority.dirty_scopes.insert(scope), // EventPriority::Low => self.low_priority.dirty_scopes.insert(scope),
// }; // };
} }
fn collect_garbage(&mut self, id: ElementId) {
//
}
} }
pub(crate) struct PriorityLane { pub(crate) struct PriorityLane {
+37 -2
View File
@@ -120,9 +120,10 @@ impl VirtualDom {
/// let mutations = dom.rebuild(); /// let mutations = dom.rebuild();
/// ``` /// ```
pub fn new_with_props<P: Properties + 'static>(root: FC<P>, root_props: P) -> Self { pub fn new_with_props<P: Properties + 'static>(root: FC<P>, root_props: P) -> Self {
let scheduler = Scheduler::new(); let root_fc = Box::new(root);
let root_props: Pin<Box<dyn Any>> = Box::pin(root_props); let root_props: Pin<Box<dyn Any>> = Box::pin(root_props);
let props_ptr = root_props.downcast_ref::<P>().unwrap() as *const P; let props_ptr = root_props.downcast_ref::<P>().unwrap() as *const P;
let root_caller: Box<dyn Fn(&Scope) -> DomTree> = Box::new(move |scope: &Scope| unsafe { let root_caller: Box<dyn Fn(&Scope) -> DomTree> = Box::new(move |scope: &Scope| unsafe {
@@ -130,6 +131,8 @@ impl VirtualDom {
std::mem::transmute(root(Context { props, scope })) std::mem::transmute(root(Context { props, scope }))
}); });
let scheduler = Scheduler::new();
let base_scope = scheduler.pool.insert_scope_with_key(|myidx| { let base_scope = scheduler.pool.insert_scope_with_key(|myidx| {
Scope::new( Scope::new(
root_caller.as_ref(), root_caller.as_ref(),
@@ -143,7 +146,7 @@ impl VirtualDom {
Self { Self {
root_caller, root_caller,
root_fc: Box::new(root), root_fc,
base_scope, base_scope,
scheduler, scheduler,
root_props, root_props,
@@ -253,6 +256,37 @@ impl VirtualDom {
/// Compute a manual diff of the VirtualDOM between states. /// Compute a manual diff of the VirtualDOM between states.
/// ///
/// This can be useful when state inside the DOM is remotely changed from the outside, but not propogated as an event. /// This can be useful when state inside the DOM is remotely changed from the outside, but not propogated as an event.
///
/// In this case, every component will be diffed, even if their props are memoized. This method is intended to be used
/// to force an update of the DOM when the state of the app is changed outside of the app.
///
///
/// # Example
/// ```rust
/// #[derive(PartialEq, Props)]
/// struct AppProps {
/// value: Shared<&'static str>,
/// }
///
/// static App: FC<AppProps> = |cx| {
/// let val = cx.value.borrow();
/// cx.render(rsx! { div { "{val}" } })
/// };
///
/// let value = Rc::new(RefCell::new("Hello"));
/// let mut dom = VirtualDom::new_with_props(
/// App,
/// AppProps {
/// value: value.clone(),
/// },
/// );
///
/// let _ = dom.rebuild();
///
/// *value.borrow_mut() = "goodbye";
///
/// let edits = dom.diff();
/// ```
pub fn diff<'s>(&'s mut self) -> Mutations<'s> { pub fn diff<'s>(&'s mut self) -> Mutations<'s> {
let cur_component = self let cur_component = self
.scheduler .scheduler
@@ -263,6 +297,7 @@ impl VirtualDom {
if cur_component.run_scope(&self.scheduler.pool) { if cur_component.run_scope(&self.scheduler.pool) {
let mut diff_machine: DiffMachine<'s> = let mut diff_machine: DiffMachine<'s> =
DiffMachine::new(Mutations::new(), &mut self.scheduler.pool); DiffMachine::new(Mutations::new(), &mut self.scheduler.pool);
diff_machine.cfg.force_diff = true;
diff_machine.diff_scope(self.base_scope); diff_machine.diff_scope(self.base_scope);
diff_machine.mutations diff_machine.mutations
} else { } else {
+3 -3
View File
@@ -13,6 +13,8 @@ type Shared<T> = Rc<RefCell<T>>;
#[test] #[test]
fn manual_diffing() { fn manual_diffing() {
test_logging::set_up_logging(IS_LOGGING_ENABLED);
#[derive(PartialEq, Props)] #[derive(PartialEq, Props)]
struct AppProps { struct AppProps {
value: Shared<&'static str>, value: Shared<&'static str>,
@@ -23,9 +25,7 @@ fn manual_diffing() {
cx.render(rsx! { div { "{val}" } }) cx.render(rsx! { div { "{val}" } })
}; };
test_logging::set_up_logging(IS_LOGGING_ENABLED); let value = Rc::new(RefCell::new("Hello"));
let mut value = Rc::new(RefCell::new("Hello"));
let mut dom = VirtualDom::new_with_props( let mut dom = VirtualDom::new_with_props(
App, App,
AppProps { AppProps {