mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-30 08:00:21 +00:00
don't subscribe in tasks or event handlers
This commit is contained in:
parent
4447709ac8
commit
0c17bdb737
6 changed files with 35 additions and 16 deletions
|
@ -73,10 +73,11 @@ pub(crate) mod innerlude {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError,
|
fc_to_builder, vdom_is_rendering, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue,
|
||||||
Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation,
|
CapturedError, Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode,
|
||||||
Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
|
LazyNodes, Mutation, Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped,
|
||||||
TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom,
|
TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText,
|
||||||
|
VirtualDom,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many common types
|
/// The purpose of this module is to alleviate imports of many common types
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::cell::{Ref, RefCell};
|
use std::cell::{Cell, Ref, RefCell};
|
||||||
|
|
||||||
use crate::{innerlude::Scheduler, scope_context::ScopeContext, scopes::ScopeId};
|
use crate::{innerlude::Scheduler, scope_context::ScopeContext, scopes::ScopeId};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -47,6 +47,7 @@ pub struct Runtime {
|
||||||
|
|
||||||
// We use this to track the current scope
|
// We use this to track the current scope
|
||||||
pub(crate) scope_stack: RefCell<Vec<ScopeId>>,
|
pub(crate) scope_stack: RefCell<Vec<ScopeId>>,
|
||||||
|
pub(crate) rendering: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Runtime {
|
impl Runtime {
|
||||||
|
@ -57,6 +58,8 @@ impl Runtime {
|
||||||
scope_contexts: Default::default(),
|
scope_contexts: Default::default(),
|
||||||
|
|
||||||
scope_stack: Default::default(),
|
scope_stack: Default::default(),
|
||||||
|
|
||||||
|
rendering: Cell::new(true),
|
||||||
});
|
});
|
||||||
runtime
|
runtime
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ impl VirtualDom {
|
||||||
|
|
||||||
// update the scope stack
|
// update the scope stack
|
||||||
self.runtime.scope_stack.borrow_mut().push(task.scope);
|
self.runtime.scope_stack.borrow_mut().push(task.scope);
|
||||||
|
self.runtime.rendering.set(false);
|
||||||
|
|
||||||
// If the task completes...
|
// If the task completes...
|
||||||
if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
|
if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
|
||||||
|
@ -33,5 +34,6 @@ impl VirtualDom {
|
||||||
|
|
||||||
// Remove the scope from the stack
|
// Remove the scope from the stack
|
||||||
self.runtime.scope_stack.borrow_mut().pop();
|
self.runtime.scope_stack.borrow_mut().pop();
|
||||||
|
self.runtime.rendering.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,12 @@ pub fn current_scope_id() -> Option<ScopeId> {
|
||||||
with_runtime(|rt| rt.current_scope_id()).flatten()
|
with_runtime(|rt| rt.current_scope_id()).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Check if the virtual dom is currently inside of the body of a component
|
||||||
|
pub fn vdom_is_rendering() -> bool {
|
||||||
|
with_runtime(|rt| rt.rendering.get()).unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume context from the current scope
|
/// Consume context from the current scope
|
||||||
pub fn consume_context<T: 'static + Clone>() -> Option<T> {
|
pub fn consume_context<T: 'static + Clone>() -> Option<T> {
|
||||||
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
||||||
|
|
|
@ -392,10 +392,12 @@ impl VirtualDom {
|
||||||
if let AttributeValue::Listener(listener) = listener {
|
if let AttributeValue::Listener(listener) = listener {
|
||||||
let origin = el_ref.scope;
|
let origin = el_ref.scope;
|
||||||
self.runtime.scope_stack.borrow_mut().push(origin);
|
self.runtime.scope_stack.borrow_mut().push(origin);
|
||||||
|
self.runtime.rendering.set(false);
|
||||||
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
||||||
cb(uievent.clone());
|
cb(uievent.clone());
|
||||||
}
|
}
|
||||||
self.runtime.scope_stack.borrow_mut().pop();
|
self.runtime.scope_stack.borrow_mut().pop();
|
||||||
|
self.runtime.rendering.set(true);
|
||||||
|
|
||||||
if !uievent.propagates.get() {
|
if !uievent.propagates.get() {
|
||||||
return;
|
return;
|
||||||
|
@ -426,10 +428,12 @@ impl VirtualDom {
|
||||||
if let AttributeValue::Listener(listener) = &attr.value {
|
if let AttributeValue::Listener(listener) = &attr.value {
|
||||||
let origin = el_ref.scope;
|
let origin = el_ref.scope;
|
||||||
self.runtime.scope_stack.borrow_mut().push(origin);
|
self.runtime.scope_stack.borrow_mut().push(origin);
|
||||||
|
self.runtime.rendering.set(false);
|
||||||
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
||||||
cb(uievent.clone());
|
cb(uievent.clone());
|
||||||
}
|
}
|
||||||
self.runtime.scope_stack.borrow_mut().pop();
|
self.runtime.scope_stack.borrow_mut().pop();
|
||||||
|
self.runtime.rendering.set(true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,17 +109,20 @@ impl<T: 'static> Signal<T> {
|
||||||
effect_subscribers.push(effect);
|
effect_subscribers.push(effect);
|
||||||
}
|
}
|
||||||
} else if let Some(current_scope_id) = current_scope_id() {
|
} else if let Some(current_scope_id) = current_scope_id() {
|
||||||
log::trace!(
|
// only subscribe if the vdom is rendering
|
||||||
"{:?} subscribed to {:?}",
|
if dioxus_core::vdom_is_rendering() {
|
||||||
self.inner.value,
|
log::trace!(
|
||||||
current_scope_id
|
"{:?} subscribed to {:?}",
|
||||||
);
|
self.inner.value,
|
||||||
let mut subscribers = inner.subscribers.borrow_mut();
|
current_scope_id
|
||||||
if !subscribers.contains(¤t_scope_id) {
|
);
|
||||||
subscribers.push(current_scope_id);
|
let mut subscribers = inner.subscribers.borrow_mut();
|
||||||
drop(subscribers);
|
if !subscribers.contains(¤t_scope_id) {
|
||||||
let unsubscriber = current_unsubscriber();
|
subscribers.push(current_scope_id);
|
||||||
inner.subscribers.borrow_mut().push(unsubscriber.scope);
|
drop(subscribers);
|
||||||
|
let unsubscriber = current_unsubscriber();
|
||||||
|
inner.subscribers.borrow_mut().push(unsubscriber.scope);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ref::map(inner, |v| &v.value)
|
Ref::map(inner, |v| &v.value)
|
||||||
|
|
Loading…
Reference in a new issue