-
Notifications
You must be signed in to change notification settings - Fork 37
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
How to turn a stream into a signal? #67
Comments
You can use However, I don't recommend that. Instead, you should use mutable_vec.signal_vec_cloned().to_signal_map(|items| {
// items is a &[T] so you can use all of the slice and Iterator methods
items.into_iter().sum()
}) mutable_vec.signal_vec_cloned().to_signal_map(|items| {
// You can return a Vec<T> by using the collect method
items.into_iter()
.scan(0, |x, y| ...)
.map(|x| ...)
.filter(|x| ...)
.collect::<Vec<_>>()
})
Whenever the The Whatever the closure returns is the value for the output So this allows you to convert a Note that if you want to get the |
Ok, but I wanted to compute the sum incrementally, so that I don't need to iterate through the whole array every time. So I thought about using the stream scan. Would that be the correct way in this case? |
In order to make something incremental, it needs to be designed to use There is already a You can't really make |
I can, if I know the current state of the vector and an item changes at a given index, I can subtract that old item and add the new one before updating the current state of the vector. The sum was just an example, what I really want is an incremental segment tree. But you think that the correct way would be extending the vector functionality? |
That would change the type signature, so it wouldn't be compatible with Also, you would still need to hold all of the items for the And because you need to store all of the old items, that means every update is Also So the performance might not be any better than
Well that's a completely different issue. Perhaps you could explain more about your use case and what you're trying to do? |
Well, I wanted to do this: a chart from a vector that could have potentially some millions of elements. The chart would agregate the data in maximum I was thinking about doing something like this with your library: I also played around with some other signal libraries, like leptos and Anchors, but I'm finding it very hard to use those signals efficiently in combination with collections, because when the collection changes, the signal fires and the computations that are listening to those don't know what changed, so they need to recompute lots of things from the collection that a lot of the times they would not really need. |
Also it looks like on rust there is always a lot of cloning involved. The libraries require the data to be clone, which makes it tricky to know when a cloning is going to happen, I makes me uneasy to work with structs that take a lot of memory space. Also when I update the signal it looks like I need to replace it, I can't mutate the data inside (not in leptos, though). |
Thanks for the explanation, I've made charts before with FRP, that is possible, and it can be done very efficiently. Aggregation is difficult to do incrementally, so you'll likely need to have an algorithm to assign each element into a bucket. For example, if the chart is ordered based on the date, you could assign each data point into buckets based on their day, week, or month. There isn't any method in
It depends on how much data you have. Rust is incredibly fast, and looping over a When performance is important, you should always benchmark instead of guessing. Especially with such a fast language like Rust.
Although that is possible, you might have an easier time if you create a custom struct that handles the updates. Also, segment trees cannot be mutated, so you'd need to recreate the entire tree from scratch on every change. If you keep the
Yes, most FRP libraries only provide simple Signals, but futures-signals has excellent collection Signals like SignalVec and SignalMap. You can also create your own custom Signals, for example a SignalTree.
That's why futures-signals always adds the It's very easy to avoid the cost of cloning: just wrap your struct in You can still mutate
That's not the case, you can use |
That's all valuable information. Thank you very much. Just one more thing. Is there a way to poll synchronously the value of a signal? Just look at it's current value without using the foreach method. |
That's almost always a bad idea. The point of signals is that they give you reactivity, getting the current value breaks reactivity. There's almost certainly a better way of accomplishing your goal without getting the current value. Having said that, you can convert the Signal into a Stream and then retrieve the next value: let mut stream = signal.to_stream();
let value1 = stream.next().await;
let value2 = stream.next().await;
let value3 = stream.next().await; |
I want to use the MutableVec to calculate, lets say, the sum of a Vector whenever something changes, to do that It seems one way would be to turn the MutableVec into a stream and them use the scan operator on it, but after that I don't want to be notified of every sum change whitout losses, I want it to behave like a signal again and get the changes only when it is polled. It would be kind of turning the stream result into a signal again. What would be the right way of doing it?
The text was updated successfully, but these errors were encountered: