Skip to content
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

Open
1 of 2 tasks
milibopp opened this issue Jan 21, 2015 · 5 comments · Fixed by #19
Open
1 of 2 tasks

Allow looping #18

milibopp opened this issue Jan 21, 2015 · 5 comments · Fixed by #19
Labels

Comments

@milibopp
Copy link
Owner

milibopp commented Jan 21, 2015

  • Looping of streams.
  • Looping of signals. How is this supposed to be defined?

Edit: terminology cell -> stream, stream -> signal

@milibopp milibopp added this to the 0.1.0 milestone Jan 21, 2015
@milibopp milibopp reopened this Jan 22, 2015
@milibopp milibopp removed this from the 0.1.0 milestone May 21, 2015
@asandroq
Copy link
Contributor

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?

@milibopp
Copy link
Owner Author

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?

@asandroq
Copy link
Contributor

Indeed, I have since realised I need a new kind of switch. I am trying to implement switch for Signal<Stream<A>> and intend to send a pull request soon.

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.

@milibopp
Copy link
Owner Author

Hm… this seems weird to me. Granted it is semantically clear what switching on a Signal<Stream<A>> ought to do. However, I am having trouble imagining how to use & implement this in a sane way, as you are potentially continuously pulling for a new push-based stream in that situation. Are you sure, you cannot model your situation with Stream::switch or Signal::switch?

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.

@asandroq
Copy link
Contributor

asandroq commented Aug 31, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants