mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 06:34:20 +00:00
wip: cleanup
This commit is contained in:
parent
6051b0ec86
commit
1745a44d94
8 changed files with 105 additions and 30 deletions
|
@ -205,13 +205,13 @@ Any function prefixed with "use" should not be called conditionally.
|
|||
///
|
||||
///
|
||||
///
|
||||
pub fn use_context_provider<T, F>(self, init: F) -> &'src Rc<T>
|
||||
pub fn use_provide_context<T, F>(self, init: F) -> &'src Rc<T>
|
||||
where
|
||||
T: 'static,
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let mut cxs = self.scope.shared_contexts.borrow_mut();
|
||||
let ty = TypeId::of::<T>();
|
||||
let contains_key = self.scope.shared_contexts.borrow().contains_key(&ty);
|
||||
|
||||
let is_initialized = self.use_hook(
|
||||
|_| false,
|
||||
|
@ -223,18 +223,29 @@ Any function prefixed with "use" should not be called conditionally.
|
|||
|_| {},
|
||||
);
|
||||
|
||||
match (is_initialized, cxs.contains_key(&ty)) {
|
||||
match (is_initialized, contains_key) {
|
||||
// Do nothing, already initialized and already exists
|
||||
(true, true) => {}
|
||||
|
||||
// Needs to be initialized
|
||||
(false, false) => {
|
||||
log::debug!("Initializing context...");
|
||||
cxs.insert(ty, Rc::new(init()));
|
||||
let initialized = Rc::new(init());
|
||||
let p = self
|
||||
.scope
|
||||
.shared_contexts
|
||||
.borrow_mut()
|
||||
.insert(ty, initialized);
|
||||
log::info!(
|
||||
"There are now {} shared contexts for scope {:?}",
|
||||
self.scope.shared_contexts.borrow().len(),
|
||||
self.scope.our_arena_idx,
|
||||
);
|
||||
}
|
||||
|
||||
_ => debug_assert!(false, "Cannot initialize two contexts of the same type"),
|
||||
};
|
||||
|
||||
self.use_context::<T>()
|
||||
}
|
||||
|
||||
|
@ -264,9 +275,17 @@ Any function prefixed with "use" should not be called conditionally.
|
|||
"Searching {:#?} for valid shared_context",
|
||||
inner.our_arena_idx
|
||||
);
|
||||
let shared_contexts = inner.shared_contexts.borrow();
|
||||
let shared_ctx = {
|
||||
let shared_contexts = inner.shared_contexts.borrow();
|
||||
|
||||
if let Some(shared_cx) = shared_contexts.get(&ty) {
|
||||
log::debug!(
|
||||
"This component has {} shared contexts",
|
||||
shared_contexts.len()
|
||||
);
|
||||
shared_contexts.get(&ty).map(|f| f.clone())
|
||||
};
|
||||
|
||||
if let Some(shared_cx) = shared_ctx {
|
||||
log::debug!("found matching cx");
|
||||
let rc = shared_cx
|
||||
.clone()
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
use crate::{arena::SharedArena, innerlude::*, tasks::TaskQueue};
|
||||
use fxhash::FxHashSet;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
|
@ -74,7 +75,7 @@ pub struct DiffMachine<'real, 'bump, Dom: RealDom<'bump>> {
|
|||
pub edits: DomEditor<'real, 'bump>,
|
||||
pub components: &'bump SharedArena,
|
||||
pub task_queue: &'bump TaskQueue,
|
||||
pub cur_idx: ScopeId,
|
||||
pub cur_idxs: SmallVec<[ScopeId; 5]>,
|
||||
pub diffed: FxHashSet<ScopeId>,
|
||||
pub event_queue: EventQueue,
|
||||
pub seen_nodes: FxHashSet<ScopeId>,
|
||||
|
@ -96,7 +97,7 @@ where
|
|||
edits: DomEditor::new(edits),
|
||||
components,
|
||||
dom,
|
||||
cur_idx,
|
||||
cur_idxs: smallvec![cur_idx],
|
||||
event_queue,
|
||||
task_queue,
|
||||
diffed: FxHashSet::default(),
|
||||
|
@ -156,6 +157,7 @@ where
|
|||
log::warn!("diffing components? {:#?}", new.user_fc);
|
||||
if old.user_fc == new.user_fc {
|
||||
// Make sure we're dealing with the same component (by function pointer)
|
||||
self.cur_idxs.push(old.ass_scope.get().unwrap());
|
||||
|
||||
// Make sure the new component vnode is referencing the right scope id
|
||||
let scope_id = old.ass_scope.get();
|
||||
|
@ -181,6 +183,7 @@ where
|
|||
} else {
|
||||
//
|
||||
}
|
||||
self.cur_idxs.pop();
|
||||
|
||||
self.seen_nodes.insert(scope_id.unwrap());
|
||||
} else {
|
||||
|
@ -399,10 +402,10 @@ where
|
|||
log::debug!("Mounting a new component");
|
||||
let caller = vcomponent.caller.clone();
|
||||
|
||||
let parent_idx = self.cur_idx;
|
||||
let parent_idx = self.cur_idxs.last().unwrap().clone();
|
||||
|
||||
// Insert a new scope into our component list
|
||||
let idx = self
|
||||
let new_idx = self
|
||||
.components
|
||||
.with(|components| {
|
||||
components.insert_with_key(|new_idx| {
|
||||
|
@ -435,20 +438,22 @@ where
|
|||
|
||||
// TODO: abstract this unsafe into the arena abstraction
|
||||
let inner: &'bump mut _ = unsafe { &mut *self.components.components.get() };
|
||||
let new_component = inner.get_mut(idx).unwrap();
|
||||
let new_component = inner.get_mut(new_idx).unwrap();
|
||||
|
||||
// Actually initialize the caller's slot with the right address
|
||||
vcomponent.ass_scope.set(Some(idx));
|
||||
vcomponent.ass_scope.set(Some(new_idx));
|
||||
|
||||
// Run the scope for one iteration to initialize it
|
||||
new_component.run_scope().unwrap();
|
||||
|
||||
// TODO: we need to delete (IE relcaim this node, otherwise the arena will grow infinitely)
|
||||
let nextnode = new_component.next_frame();
|
||||
self.cur_idxs.push(new_idx);
|
||||
let meta = self.create(nextnode);
|
||||
self.cur_idxs.pop();
|
||||
|
||||
// Finally, insert this node as a seen node.
|
||||
self.seen_nodes.insert(idx);
|
||||
self.seen_nodes.insert(new_idx);
|
||||
|
||||
CreateMeta::new(vcomponent.is_static, meta.added_to_stack)
|
||||
}
|
||||
|
|
|
@ -533,6 +533,17 @@ impl<'a> IntoVNode<'a> for Option<VNode<'a>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoVNode<'_> for &'static str {
|
||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||
NodeFactory::static_text(self)
|
||||
}
|
||||
}
|
||||
impl IntoVNode<'_> for Arguments<'_> {
|
||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||
cx.text(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NodeFactory<'_> {
|
||||
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Ok(())
|
||||
|
|
|
@ -51,8 +51,7 @@
|
|||
const node = self.stack.pop();
|
||||
node.remove();
|
||||
}
|
||||
RemoveAllChildren(self, edit) {
|
||||
}
|
||||
RemoveAllChildren(self, edit) {}
|
||||
CreateTextNode(self, edit) {
|
||||
self.stack.push(document.createTextNode(edit.text));
|
||||
}
|
||||
|
@ -62,24 +61,32 @@
|
|||
self.stack.push(document.createElement(tagName));
|
||||
}
|
||||
CreateElementNs(self, edit) {
|
||||
const tagName = edit.tag;
|
||||
console.log(`creating namespaced element: `, edit);
|
||||
self.stack.push(document.createElementNS(edit.ns, edit.tag));
|
||||
}
|
||||
CreatePlaceholder(self, edit) {
|
||||
const a = `self.stack.push(document.createElement("pre"))`;
|
||||
self.stack.push(document.createComment("vroot"));
|
||||
}
|
||||
NewEventListener(self, edit) {
|
||||
}
|
||||
RemoveEventListener(self, edit) {
|
||||
}
|
||||
NewEventListener(self, edit) {}
|
||||
RemoveEventListener(self, edit) {}
|
||||
SetText(self, edit) {
|
||||
self.top().textContent = edit.text;
|
||||
}
|
||||
SetAttribute(self, edit) {
|
||||
const name = edit.field;
|
||||
const value = edit.value;
|
||||
const ns = edit.ns;
|
||||
|
||||
const node = self.top(self.stack);
|
||||
node.setAttribute(name, value);
|
||||
if (ns == "style") {
|
||||
node.style[name] = value;
|
||||
} else if (ns !== undefined) {
|
||||
node.setAttributeNS(ns, name, value);
|
||||
} else {
|
||||
node.setAttribute(name, value);
|
||||
}
|
||||
|
||||
if ((name === "value", self)) {
|
||||
node.value = value;
|
||||
|
@ -94,6 +101,7 @@
|
|||
RemoveAttribute(self, edit) {
|
||||
const name = edit.field;
|
||||
const node = self.top(self.stack);
|
||||
|
||||
node.removeAttribute(name);
|
||||
|
||||
if ((name === "value", self)) {
|
||||
|
|
|
@ -2,13 +2,13 @@ use dioxus_core::prelude::Context;
|
|||
use std::{
|
||||
cell::{Cell, Ref, RefCell, RefMut},
|
||||
fmt::Display,
|
||||
ops::{Deref, DerefMut},
|
||||
ops::{Deref, DerefMut, Not},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
/// Store state between component renders!
|
||||
///
|
||||
/// ## The "King" of state hooks
|
||||
/// ## The "Pinnacle" of state hooks
|
||||
///
|
||||
/// The Dioxus version of `useState` is the "king daddy" of state management. It allows you to ergonomically store and
|
||||
/// modify state between component renders. When the state is updated, the component will re-render.
|
||||
|
@ -129,6 +129,10 @@ impl<'a, T: 'static> UseState<'a, T> {
|
|||
wip: self.inner.wip.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_for_async(&'a self) -> (&'a Self, AsyncUseState<T>) {
|
||||
(self, self.for_async())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'static + ToOwned<Owned = T>> UseState<'a, T> {
|
||||
|
@ -147,15 +151,15 @@ impl<'a, T: 'static + ToOwned<Owned = T>> UseState<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'static> std::ops::Deref for UseState<'a, T> {
|
||||
impl<'a, T> std::ops::Deref for UseState<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner.current_val
|
||||
self.get()
|
||||
}
|
||||
}
|
||||
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||
|
||||
impl<'a, T: Copy + Add<T, Output = T>> Add<T> for UseState<'a, T> {
|
||||
type Output = T;
|
||||
|
@ -208,6 +212,18 @@ impl<'a, T: Copy + Div<T, Output = T>> DivAssign<T> for UseState<'a, T> {
|
|||
self.set(self.inner.current_val.div(rhs));
|
||||
}
|
||||
}
|
||||
impl<'a, T: PartialEq<T>> PartialEq<T> for UseState<'a, T> {
|
||||
fn eq(&self, other: &T) -> bool {
|
||||
self.get() == other
|
||||
}
|
||||
}
|
||||
impl<'a, O, T: Not<Output = O> + Copy> Not for UseState<'a, T> {
|
||||
type Output = O;
|
||||
|
||||
fn not(self) -> Self::Output {
|
||||
!*self.get()
|
||||
}
|
||||
}
|
||||
|
||||
// enable displaty for the handle
|
||||
impl<'a, T: 'static + Display> std::fmt::Display for UseState<'a, T> {
|
||||
|
@ -233,4 +249,7 @@ impl<T: ToOwned> AsyncUseState<T> {
|
|||
slot.as_mut().unwrap()
|
||||
})
|
||||
}
|
||||
pub fn set(&mut self, val: T) {
|
||||
*self.wip.borrow_mut() = Some(val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ use dioxus_core::*;
|
|||
|
||||
pub fn render_vnode(vnode: &VNode, string: &mut String) {}
|
||||
|
||||
pub fn render_vdom(vdom: &VirtualDom) -> String {
|
||||
format!("{:}", TextRenderer::from_vdom(vdom))
|
||||
pub fn render_vdom(dom: &VirtualDom) -> String {
|
||||
format!("{:}", TextRenderer::from_vdom(dom))
|
||||
}
|
||||
|
||||
pub fn render_vdom_scope(vdom: &VirtualDom, scope: ScopeId) -> Option<String> {
|
||||
|
|
|
@ -17,7 +17,6 @@ wasm-bindgen-futures = "0.4.20"
|
|||
wasm-logger = "0.2.0"
|
||||
log = "0.4.14"
|
||||
fxhash = "0.2.1"
|
||||
pretty_env_logger = "0.4.0"
|
||||
console_error_panic_hook = "0.1.6"
|
||||
generational-arena = "0.2.8"
|
||||
wasm-bindgen-test = "0.3.21"
|
||||
|
@ -60,6 +59,8 @@ features = [
|
|||
"CompositionEvent",
|
||||
"DocumentType",
|
||||
"CharacterData",
|
||||
"SvgElement",
|
||||
"SvgAnimatedString",
|
||||
"HtmlOptionElement",
|
||||
]
|
||||
|
||||
|
|
|
@ -294,8 +294,20 @@ impl WebsysDom {
|
|||
|
||||
fn set_attribute(&mut self, name: &str, value: &str, ns: Option<&str>) {
|
||||
if name == "class" {
|
||||
if let Some(el) = self.stack.top().dyn_ref::<Element>() {
|
||||
el.set_class_name(value);
|
||||
match ns {
|
||||
Some("http://www.w3.org/2000/svg") => {
|
||||
//
|
||||
if let Some(el) = self.stack.top().dyn_ref::<web_sys::SvgElement>() {
|
||||
let r: web_sys::SvgAnimatedString = el.class_name();
|
||||
r.set_base_val(value);
|
||||
// el.set_class_name(value);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(el) = self.stack.top().dyn_ref::<Element>() {
|
||||
el.set_class_name(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(el) = self.stack.top().dyn_ref::<Element>() {
|
||||
|
|
Loading…
Reference in a new issue