wip: clean up, use old approach to components
This commit is contained in:
1 parent
289d2f2518
commit
2559740463
18 files changed
+180
-247
No files matched your search
@@ -20,21 +20,13 @@
|
||||
//! Additional functionality is defined in the respective files.
|
||||
|
||||
use crate::innerlude::*;
|
||||
use bumpalo::Bump;
|
||||
use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||
use futures_util::{pin_mut, stream::FuturesUnordered, Future, FutureExt, StreamExt};
|
||||
use fxhash::FxHashMap;
|
||||
use futures_util::{Future, StreamExt};
|
||||
use fxhash::FxHashSet;
|
||||
use indexmap::IndexSet;
|
||||
use slab::Slab;
|
||||
use std::pin::Pin;
|
||||
use std::task::Poll;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
cell::{Cell, UnsafeCell},
|
||||
collections::{HashSet, VecDeque},
|
||||
rc::Rc,
|
||||
};
|
||||
use std::{any::Any, collections::VecDeque};
|
||||
|
||||
/// An integrated virtual node system that progresses events and diffs UI trees.
|
||||
///
|
||||
@@ -69,10 +61,7 @@ use std::{
|
||||
pub struct VirtualDom {
|
||||
base_scope: ScopeId,
|
||||
|
||||
_root_props: Rc<dyn Any>,
|
||||
|
||||
// we need to keep the allocation around, but we don't necessarily use it
|
||||
_root_caller: Box<dyn Any>,
|
||||
_root_caller: *mut dyn Fn(&Scope) -> Element,
|
||||
|
||||
pub(crate) scopes: ScopeArena,
|
||||
|
||||
@@ -156,30 +145,22 @@ impl VirtualDom {
|
||||
sender: UnboundedSender<SchedulerMsg>,
|
||||
receiver: UnboundedReceiver<SchedulerMsg>,
|
||||
) -> Self {
|
||||
let mut scopes = ScopeArena::new(sender);
|
||||
let mut scopes = ScopeArena::new(sender.clone());
|
||||
|
||||
let base_scope = scopes.new_with_key(
|
||||
//
|
||||
root as _,
|
||||
todo!(),
|
||||
// boxed_comp.as_ref(),
|
||||
None,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
let caller = Box::new(move |f: &Scope| -> Element { root(f, &root_props) });
|
||||
let caller_ref: *mut dyn Fn(&Scope) -> Element = Box::into_raw(caller);
|
||||
let base_scope = scopes.new_with_key(root as _, caller_ref, None, 0, 0);
|
||||
|
||||
Self {
|
||||
scopes,
|
||||
base_scope,
|
||||
receiver,
|
||||
sender,
|
||||
|
||||
_root_props: todo!(),
|
||||
_root_caller: todo!(),
|
||||
|
||||
// todo: clean this up manually?
|
||||
_root_caller: caller_ref,
|
||||
pending_messages: VecDeque::new(),
|
||||
pending_futures: Default::default(),
|
||||
dirty_scopes: Default::default(),
|
||||
sender,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +170,7 @@ impl VirtualDom {
|
||||
/// directly.
|
||||
///
|
||||
/// # Example
|
||||
pub fn base_scope(&self) -> &ScopeState {
|
||||
pub fn base_scope(&self) -> &Scope {
|
||||
self.get_scope(&self.base_scope).unwrap()
|
||||
}
|
||||
|
||||
@@ -199,7 +180,7 @@ impl VirtualDom {
|
||||
///
|
||||
///
|
||||
///
|
||||
pub fn get_scope<'a>(&'a self, id: &ScopeId) -> Option<&'a ScopeState> {
|
||||
pub fn get_scope<'a>(&'a self, id: &ScopeId) -> Option<&'a Scope> {
|
||||
self.scopes.get_scope(id)
|
||||
}
|
||||
|
||||
@@ -402,7 +383,7 @@ impl VirtualDom {
|
||||
|
||||
log::debug!("about to run scope {:?}", scopeid);
|
||||
|
||||
if self.run_scope(&scopeid) {
|
||||
if self.scopes.run_scope(&scopeid) {
|
||||
let scope = self.scopes.get_scope(&scopeid).unwrap();
|
||||
let (old, new) = (scope.wip_head(), scope.fin_head());
|
||||
diff_state.stack.scope_stack.push(scopeid);
|
||||
@@ -503,7 +484,7 @@ impl VirtualDom {
|
||||
pub fn hard_diff<'a>(&'a mut self, scope_id: &ScopeId) -> Option<Mutations<'a>> {
|
||||
log::debug!("hard diff {:?}", scope_id);
|
||||
|
||||
if self.run_scope(scope_id) {
|
||||
if self.scopes.run_scope(scope_id) {
|
||||
let mut diff_machine = DiffState::new(Mutations::new());
|
||||
|
||||
diff_machine.force_diff = true;
|
||||
@@ -515,61 +496,6 @@ impl VirtualDom {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn run_scope(&self, id: &ScopeId) -> bool {
|
||||
let scope = self
|
||||
.scopes
|
||||
.get_scope(id)
|
||||
.expect("The base scope should never be moved");
|
||||
|
||||
// Cycle to the next frame and then reset it
|
||||
// This breaks any latent references, invalidating every pointer referencing into it.
|
||||
// Remove all the outdated listeners
|
||||
self.scopes.ensure_drop_safety(id);
|
||||
|
||||
// Safety:
|
||||
// - We dropped the listeners, so no more &mut T can be used while these are held
|
||||
// - All children nodes that rely on &mut T are replaced with a new reference
|
||||
unsafe { scope.hooks.reset() };
|
||||
|
||||
// Safety:
|
||||
// - We've dropped all references to the wip bump frame with "ensure_drop_safety"
|
||||
unsafe { scope.reset_wip_frame() };
|
||||
|
||||
let mut items = scope.items.borrow_mut();
|
||||
|
||||
// just forget about our suspended nodes while we're at it
|
||||
items.suspended_nodes.clear();
|
||||
|
||||
// guarantee that we haven't screwed up - there should be no latent references anywhere
|
||||
debug_assert!(items.listeners.is_empty());
|
||||
debug_assert!(items.suspended_nodes.is_empty());
|
||||
debug_assert!(items.borrowed_props.is_empty());
|
||||
|
||||
log::debug!("Borrowed stuff is successfully cleared");
|
||||
|
||||
// temporarily cast the vcomponent to the right lifetime
|
||||
// let vcomp = scope.load_vcomp();
|
||||
|
||||
let render: &dyn Fn(&ScopeState) -> Element = todo!();
|
||||
|
||||
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
||||
if let Some(key) = render(scope) {
|
||||
// todo!("attach the niode");
|
||||
// let new_head = builder.into_vnode(NodeFactory {
|
||||
// bump: &scope.frames.wip_frame().bump,
|
||||
// });
|
||||
// log::debug!("Render is successful");
|
||||
|
||||
// the user's component succeeded. We can safely cycle to the next frame
|
||||
// scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
|
||||
// scope.frames.cycle_frame();
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SchedulerMsg {
|
||||
|
||||
Reference in new issue
Block a user