mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
Fix some ownership clashes by using grow-only Vecs to hold signal/memo/effect state
This commit is contained in:
parent
4a7154071e
commit
3e4adcad21
7 changed files with 36 additions and 40 deletions
|
@ -86,10 +86,10 @@ fn Counter(
|
|||
view! {
|
||||
<li>
|
||||
<button on:click={move |_| set_value(|value| *value -= 1)}>"-1"</button>
|
||||
/* <input type="text"
|
||||
prop:value={let value = value.clone(); move || value().to_string()}
|
||||
<input type="text"
|
||||
prop:value={move || value().to_string()}
|
||||
on:input=input
|
||||
/> */
|
||||
/>
|
||||
<span>{move || value().to_string()}</span>
|
||||
<button on:click=move |_| set_value(|value| *value += 1)>"+1"</button>
|
||||
<button on:click=move |_| set_counters(|counters| counters.retain(|(counter_id, _)| counter_id != &id))>"x"</button>
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
log = "0.4"
|
||||
slotmap = { version = "1", features = ["serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
debug-cell = "0.1"
|
||||
elsa = "1.7.0"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen-futures = "0.4"
|
||||
wasm-bindgen-futures = "0.4"
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use crate::{Runtime, Scope, ScopeId, Source, Subscriber};
|
||||
use debug_cell::RefCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
any::type_name, /* cell::RefCell, */ collections::HashSet, fmt::Debug, marker::PhantomData,
|
||||
};
|
||||
use std::{any::type_name, cell::RefCell, collections::HashSet, fmt::Debug, marker::PhantomData};
|
||||
|
||||
impl Scope {
|
||||
pub fn create_effect<T>(self, f: impl FnMut(Option<T>) -> T + 'static) -> Effect<T>
|
||||
|
@ -20,9 +17,9 @@ impl Scope {
|
|||
ty: PhantomData,
|
||||
};
|
||||
|
||||
/* self.runtime
|
||||
.any_effect((self.id, id), |effect| effect.run((self.id, id)));
|
||||
*/
|
||||
self.runtime
|
||||
.any_effect((self.id, id), |effect| effect.run((self.id, id)));
|
||||
|
||||
eff
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +46,8 @@ impl<T> Clone for Effect<T> {
|
|||
|
||||
impl<T> Copy for Effect<T> {}
|
||||
|
||||
slotmap::new_key_type! { pub(crate) struct EffectId; }
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub(crate) struct EffectId(pub(crate) usize);
|
||||
|
||||
pub(crate) struct EffectState<T> {
|
||||
runtime: &'static Runtime,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{Runtime, Scope, ScopeId, Source, Subscriber};
|
||||
use std::{
|
||||
any::{type_name, Any},
|
||||
|
@ -103,7 +105,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
slotmap::new_key_type! { pub(crate) struct MemoId; }
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub(crate) struct MemoId(pub(crate) usize);
|
||||
|
||||
pub(crate) struct MemoState<T>
|
||||
where
|
||||
|
|
|
@ -25,13 +25,9 @@ impl Runtime {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn any_effect<T>(
|
||||
&self,
|
||||
id: (ScopeId, EffectId),
|
||||
f: impl FnOnce(&Box<dyn AnyEffect>) -> T,
|
||||
) -> T {
|
||||
pub fn any_effect<T>(&self, id: (ScopeId, EffectId), f: impl FnOnce(&dyn AnyEffect) -> T) -> T {
|
||||
self.scope(id.0, |scope| {
|
||||
if let Some(n) = scope.effects.borrow().get(id.1) {
|
||||
if let Some(n) = scope.effects.get(id.1 .0) {
|
||||
(f)(n)
|
||||
} else {
|
||||
panic!("couldn't locate {id:?}");
|
||||
|
@ -39,9 +35,9 @@ impl Runtime {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn any_memo<T>(&self, id: (ScopeId, MemoId), f: impl FnOnce(&Box<dyn AnyMemo>) -> T) -> T {
|
||||
pub fn any_memo<T>(&self, id: (ScopeId, MemoId), f: impl FnOnce(&dyn AnyMemo) -> T) -> T {
|
||||
self.scope(id.0, |scope| {
|
||||
if let Some(n) = scope.memos.borrow().get(id.1) {
|
||||
if let Some(n) = scope.memos.get(id.1 .0) {
|
||||
(f)(n)
|
||||
} else {
|
||||
panic!("couldn't locate {id:?}");
|
||||
|
@ -65,13 +61,9 @@ impl Runtime {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn any_signal<T>(
|
||||
&self,
|
||||
id: (ScopeId, SignalId),
|
||||
f: impl FnOnce(&Box<dyn AnySignal>) -> T,
|
||||
) -> T {
|
||||
pub fn any_signal<T>(&self, id: (ScopeId, SignalId), f: impl FnOnce(&dyn AnySignal) -> T) -> T {
|
||||
self.scope(id.0, |scope| {
|
||||
if let Some(n) = scope.signals.borrow().get(id.1) {
|
||||
if let Some(n) = scope.signals.get(id.1 .0) {
|
||||
(f)(n)
|
||||
} else {
|
||||
panic!("couldn't locate {id:?}");
|
||||
|
|
|
@ -2,11 +2,10 @@ use crate::{
|
|||
AnyEffect, AnyMemo, AnySignal, EffectId, EffectState, MemoId, MemoState, Runtime, SignalId,
|
||||
SignalState,
|
||||
};
|
||||
use debug_cell::RefCell;
|
||||
use slotmap::SlotMap;
|
||||
use elsa::FrozenVec;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
/* cell::RefCell, */
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
fmt::Debug,
|
||||
};
|
||||
|
@ -42,7 +41,8 @@ impl Scope {
|
|||
T: Debug + 'static,
|
||||
{
|
||||
self.runtime.scope(self.id, |scope| {
|
||||
scope.signals.borrow_mut().insert(Box::new(state))
|
||||
scope.signals.push(Box::new(state));
|
||||
SignalId(scope.signals.len() - 1)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,8 @@ impl Scope {
|
|||
T: Debug + 'static,
|
||||
{
|
||||
self.runtime.scope(self.id, |scope| {
|
||||
scope.effects.borrow_mut().insert(Box::new(state))
|
||||
scope.effects.push(Box::new(state));
|
||||
EffectId(scope.effects.len() - 1)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,8 @@ impl Scope {
|
|||
T: Debug + 'static,
|
||||
{
|
||||
self.runtime.scope(self.id, |scope| {
|
||||
scope.memos.borrow_mut().insert(Box::new(state))
|
||||
scope.memos.push(Box::new(state));
|
||||
MemoId(scope.memos.len() - 1)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -95,9 +97,9 @@ pub(crate) struct ScopeState {
|
|||
pub(crate) parent: Option<Scope>,
|
||||
pub(crate) contexts: RefCell<HashMap<TypeId, Box<dyn Any>>>,
|
||||
pub(crate) children: RefCell<Vec<ScopeId>>,
|
||||
pub(crate) signals: RefCell<SlotMap<SignalId, Box<dyn AnySignal>>>,
|
||||
pub(crate) memos: RefCell<SlotMap<MemoId, Box<dyn AnyMemo>>>,
|
||||
pub(crate) effects: RefCell<SlotMap<EffectId, Box<dyn AnyEffect>>>,
|
||||
pub(crate) signals: FrozenVec<Box<dyn AnySignal>>,
|
||||
pub(crate) memos: FrozenVec<Box<dyn AnyMemo>>,
|
||||
pub(crate) effects: FrozenVec<Box<dyn AnyEffect>>,
|
||||
}
|
||||
|
||||
impl Debug for ScopeState {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{Runtime, Scope, ScopeId, Source, Subscriber};
|
||||
use debug_cell::RefCell;
|
||||
use std::{any::Any, /* cell::RefCell, */ collections::HashSet, fmt::Debug, marker::PhantomData,};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{any::Any, cell::RefCell, collections::HashSet, fmt::Debug, marker::PhantomData};
|
||||
|
||||
impl Scope {
|
||||
pub fn create_signal<T>(self, value: T) -> (ReadSignal<T>, WriteSignal<T>)
|
||||
|
@ -211,7 +211,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
slotmap::new_key_type! { pub(crate) struct SignalId; }
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub(crate) struct SignalId(pub(crate) usize);
|
||||
|
||||
//#[derive(Debug)]
|
||||
pub(crate) struct SignalState<T> {
|
||||
|
|
Loading…
Reference in a new issue