-
-
Notifications
You must be signed in to change notification settings - Fork 650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signal<T, S = SyncStorage>
doesn't implement Track
#2976
Comments
Note that it's not possible to implement A derived If it's just a question of API design and you want to be able to take Open to being wrong. |
Thanks for that comprehensive explanation. In fact I didn't think of it that deeply. I ran into this when porting the new Now I indeed resorted to So I think there might be some valid use cases for having |
Chiming in, not having track seems to prevent let foo = RwSignal::new(0);
let bar = Signal::derive(|| &*foo.read() + 1); // Success
let baz = Signal::derive(|| &*bar.read() + 1); // doesn't satisfy `_: ReadUntracked`, `_: Read` or `_: Track` ps. I understand this example would work if I just used |
Again, this is because it isn't possible, and the trait system is trying to avoid lying to you, arguably at the expense of ergonomics. In fact, I want to distinguish really carefully between "possible on signals" and "possible on the If you're in a situation where using |
Whoops sorry definitely didn't mean to include Understood on the way Signal fakes I think this logic might also apply to what @maccesch was porting over from 0.6, if it was using that "faking it" clone prior anyway. Wouldn't something along the lines of this work, it seems to compile: ///
pub enum SignalReadGuard<T: 'static, S: Storage<T>> {
///
Read(ReadGuard<T, Plain<T>>),
///
Memo(ReadGuard<T, Mapped<Plain<MemoInner<T, S>>, T>>),
///
Derived(T),
}
impl<T, S> Deref for SignalReadGuard<T, S>
where
T: 'static,
S: Storage<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
SignalReadGuard::Read(i) => i,
SignalReadGuard::Memo(i) => i,
SignalReadGuard::Derived(i) => i,
}
}
}
impl<T, S> ReadUntracked for ArcSignal<T, S>
where
S: Storage<T>,
T: Clone,
{
type Value = SignalReadGuard<T, S>;
fn try_read_untracked(&self) -> Option<Self::Value> {
match &self.inner {
SignalTypes::ReadSignal(i) => i.try_read_untracked().map(SignalReadGuard::Read),
SignalTypes::Memo(i) => i.try_read_untracked().map(SignalReadGuard::Memo),
SignalTypes::DerivedSignal(i) => {
Some(SignalReadGuard::Derived(untrack(|| i())))
},
}
}
}
impl<T, S> Read for ArcSignal<T, S>
where
S: Storage<T>,
T: Clone,
{
type Value = SignalReadGuard<T, S>;
fn try_read(&self) -> Option<Self::Value> {
match &self.inner {
SignalTypes::ReadSignal(i) => i.try_read().map(SignalReadGuard::Read),
SignalTypes::Memo(i) => i.try_read().map(SignalReadGuard::Memo),
SignalTypes::DerivedSignal(i) => {
Some(SignalReadGuard::Derived(i()))
},
}
}
fn read(&self) -> Self::Value {
self.try_read().unwrap_or_else(unwrap_signal!(self))
}
} I imagine it would be similar for the track trait, just no special guard. |
Added by #3031. |
No description provided.
The text was updated successfully, but these errors were encountered: