Feat: major overhaul to diffing, using a "diffing machine" now
This commit is contained in:
1 parent
4c291a0efd
commit
4dfdf91236
10 files changed
+822
-780
No files matched your search
@@ -1,11 +1,11 @@
|
||||
use crate::context::hooks::Hook;
|
||||
use crate::innerlude::*;
|
||||
use crate::nodes::VNode;
|
||||
use crate::{context::hooks::Hook, diff::diff};
|
||||
use bumpalo::Bump;
|
||||
use generational_arena::Index;
|
||||
use std::{
|
||||
any::TypeId, borrow::Borrow, cell::RefCell, future::Future, marker::PhantomData,
|
||||
sync::atomic::AtomicUsize,
|
||||
sync::atomic::AtomicUsize, todo,
|
||||
};
|
||||
|
||||
/// Every component in Dioxus is represented by a `Scope`.
|
||||
@@ -29,9 +29,13 @@ pub struct Scope {
|
||||
pub frames: [Bump; 2],
|
||||
|
||||
// somehow build this vnode with a lifetime tied to self
|
||||
pub cur_node: *mut VNode<'static>,
|
||||
// This root node has "static" lifetime, but it's really not static.
|
||||
// It's goverened by the oldest of the two frames and is switched every time a new render occurs
|
||||
// Use this node as if it were static is unsafe, and needs to be fixed with ourborous or owning ref
|
||||
// ! do not copy this reference are things WILL break !
|
||||
pub root_node: *mut VNode<'static>,
|
||||
|
||||
pub active_frame: u8,
|
||||
pub active_frame: ActiveFrame,
|
||||
|
||||
// IE Which listeners need to be woken up?
|
||||
pub listeners: Vec<Box<dyn Fn()>>,
|
||||
@@ -41,6 +45,20 @@ pub struct Scope {
|
||||
pub caller: *const i32,
|
||||
}
|
||||
|
||||
pub enum ActiveFrame {
|
||||
First,
|
||||
Second,
|
||||
}
|
||||
|
||||
impl ActiveFrame {
|
||||
fn next(&mut self) {
|
||||
match self {
|
||||
ActiveFrame::First => *self = ActiveFrame::Second,
|
||||
ActiveFrame::Second => *self = ActiveFrame::First,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
// create a new scope from a function
|
||||
pub(crate) fn new<T: 'static>(f: FC<T>, parent: Option<Index>) -> Self {
|
||||
@@ -49,15 +67,19 @@ impl Scope {
|
||||
let hook_arena = typed_arena::Arena::new();
|
||||
let hooks = RefCell::new(Vec::new());
|
||||
|
||||
// Capture the caller
|
||||
let caller = f as *const i32;
|
||||
|
||||
// Create the two buffers the componetn will render into
|
||||
// There will always be an "old" and "new"
|
||||
let frames = [Bump::new(), Bump::new()];
|
||||
|
||||
let listeners = Vec::new();
|
||||
|
||||
let active_frame = 1;
|
||||
let active_frame = ActiveFrame::First;
|
||||
|
||||
let new = frames[0].alloc(VNode::Text(VText::new("")));
|
||||
|
||||
let cur_node = new as *mut _;
|
||||
|
||||
Self {
|
||||
@@ -69,7 +91,7 @@ impl Scope {
|
||||
listeners,
|
||||
parent,
|
||||
frames,
|
||||
cur_node,
|
||||
root_node: cur_node,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +100,12 @@ impl Scope {
|
||||
///
|
||||
/// Props is ?Sized because we borrow the props and don't need to know the size. P (sized) is used as a marker (unsized)
|
||||
pub(crate) fn run<'a, P: Properties + ?Sized>(&self, props: &'a P) {
|
||||
let bump = &self.frames[0];
|
||||
let bump = match self.active_frame {
|
||||
// If the active frame is the first, then we need to bump into the second
|
||||
ActiveFrame::First => &self.frames[1],
|
||||
// If the active frame is the second, then we need to bump into the first
|
||||
ActiveFrame::Second => &self.frames[0],
|
||||
}; // n.b, there might be a better way of doing this active frame stuff - perhaps swapping
|
||||
|
||||
let ctx = Context {
|
||||
scope: &*self,
|
||||
@@ -102,13 +129,14 @@ impl Scope {
|
||||
*/
|
||||
let caller = unsafe { std::mem::transmute::<*const i32, FC<P>>(self.caller) };
|
||||
let new_nodes = caller(ctx, props);
|
||||
let old_nodes: &mut VNode<'static> = unsafe { &mut *self.cur_node };
|
||||
let old_nodes: &mut VNode<'static> = unsafe { &mut *self.root_node };
|
||||
|
||||
// TODO: Iterate through the new nodes
|
||||
// move any listeners into ourself
|
||||
|
||||
// perform the diff, dumping into the mutable change list
|
||||
// this doesnt perform any "diff compression" where an event and a re-render
|
||||
crate::diff::diff(old_nodes, &new_nodes);
|
||||
// crate::diff::diff(old_nodes, &new_nodes);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user