-
Notifications
You must be signed in to change notification settings - Fork 19
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
Allow looping #18
Comments
The looping of streams would be really useful to me, as I am trying to implement a stream that switch a game between different screens. Are there any ideas about how this could be implemented? |
Note, that the terminology in carboxyl has changed, since I wrote this issue. It's no longer cell/stream, but stream/signal, where signal is the continuously changing value and a stream is a discrete sequence of events. I am not sure, what your use case looks like precisely, but it sounds like Signal::switch could help? |
Indeed, I have since realised I need a new kind of I need this because embedded in the current state of the game there is a stream that will fire when the users want to change screens, for instance when opening the preferences window or pausing the game. |
Hm… this seems weird to me. Granted it is semantically clear what switching on a Also note that quite a few FRP systems leave out dynamic switching entirely. This is mostly because they have somewhat complex semantics if you want to make your system purely declarative. And it is perfectly possible to model event systems without this feature altogether. |
I have implemented it already, but I am trying to get a stronger version of it which is self-referential. So, currently, this works: fn switch_signal_stream() {
let control_sink = Sink::new();
let control_stream = control_sink.stream();
let sink1 = Sink::new();
let sink2 = Sink::new();
let mut switched = control_stream.fold(sink1.stream(), |_, s| s).switch().events();
sink2.send(1);
sink1.send(2);
assert_eq!(switched.next(), Some(2));
control_sink.send(sink2.stream());
sink1.send(3);
sink2.send(4);
assert_eq!(switched.next(), Some(4));
control_sink.send(sink1.stream());
sink2.send(5);
sink1.send(6);
assert_eq!(switched.next(), Some(6));
} But this panics: fn switch_signal_stream_self_referential() {
#[derive(Clone)]
struct Control {
change: Stream<Control>,
value: i32,
}
let sink1 = Sink::new();
//let sink2 = Sink::new();
let initial = Control {
change: sink1.stream(),
value: 1,
};
let sig = Signal::<Control>::cyclic(|sig| {
let str = sig.map(|c| c.change).switch();
sig.snapshot(&str, |_, c| c).hold(initial)
});
assert_eq!(sig.sample().value, 1);
} The reason I want the self-referential version is that I think it expresses my intent more clearly, but that's maybe because I am a Haskell programmer and there we have laziness. My intent is to have a GameControl struct which I will sample at every frame tick after the game logic has run. This logic will include a stream that will tell the game to switch to another mode (menu screen, paused screen etc.). I tried to model this with the current API but could not find a way. |
Edit: terminology cell -> stream, stream -> signal
The text was updated successfully, but these errors were encountered: