Dynamic Event Switching in Reactive-Banana
Asked Answered
N

1

8

I am currently working on a small game utilizing reactive banana and SDL. Since the goal is mostly to learn more about reactive banana and FRP, I attempted to use dynamic switching to set up a collection of game objects, but without much success so far.

In the Bartab example, the only example that uses event switching I've found, the event that ultimately triggers the creation of a new entry in the collection is acquired from outside the event network instead of using an internal event. My question is: Is this the only way to do it or is it just a special case for this example?

Are there any more examples of dynamic event switching being used in reactive banana?

From what I understand I get a Moment t (Anytime Behavior a), use execute to create an Event t (Anytime Behavior a), which is then in turn used to update the Behavior carrying the collection. The Moment t (Anytime Behavior a) is created using trimB on a Behavior created from the triggering Event. If this triggering event originates in the event network, it doesn't compile with the error message "Could not deduce (t ~ t1)". I'm not sure what the ~ exactly means, but it obviously throws the error because the two Frameworks values (t) of the event network and this new Moment value are different.

So, long story short, I don't understand how Event Switching in reactive banana works and I'm not sure why. It should be relatively straightforward in theory.

Edit:

-- Event Network
-- ==========================
setupNetwork :: forall t. Frameworks t => (EventSource Command, EventSource ()) -> IORef SpriteMap -> GameMap -> Moment t ()
setupNetwork ((addHandlerE, _), (addHandlerT, _)) sprites map = do

        -- Input Events
        ----------------
        eInput <- fromAddHandler addHandlerE -- Player Commands
        eFrame <- fromAddHandler addHandlerT -- Event on each Frame

        let
            [...]


            eSpawnEvent :: Event t (DSCoord)
            eSpawnEvent = extractCoord <$> eLeftClick 
                where
                        extractCoord (LeftClick c) = c

            spawnPos :: Frameworks s => Moment s (AnyMoment Behavior DSCoord)
            spawnPos = trimB $ stepper (0,0) eSpawnEvent

        eSpawnPos <- execute $ (FrameworksMoment spawnPos <$ eSpawnEvent)
                [...]

I simply tried to mirror newEntry / eNewEntry from the example, just using a normal event to create the new behavior. This produces the "Could not deduce (t ~ s)" error in spawnPos.

Edit2:

It works, but now the same error comes up on the line where I use execute to create the Event. "Could not deduce t ~ t1"

Novellanovello answered 1/3, 2013 at 17:27 Comment(2)
I think it might help a lot if you post your example code that doesn't compile?Mopey
I updated the question with a code example.Novellanovello
M
3

It appears to me that the code is essentially correct except for a minor mistake:

The compiler rightly complains that spawnPos has a (polymorphic) starting time s while the starting time of eSpawnEvent is fixed to t, which is different. The latter time is brought into scope via the forall t part in type signature of setupNetwork. In other words, t represents the starting time of the whole network.

The simple fix is to change the offending line to

spawnPos :: Frameworks t => Moment t (AnyMoment Behavior DSCoord)
Mopey answered 3/3, 2013 at 8:46 Comment(5)
Thank you, it helped, but not completely.Novellanovello
I edited the question again, in case you didn't see it. It's still the same error.Novellanovello
Ah, I see. Posting the code and the specific error message from GHC (which also shows the expression affected) always helps. The problem in your case is that your use of FrameworksMoment spawnPos does not give the right type for eSpawnPos even once your other problems are fixed. You have to convert the AnyMoment thing to a FrameworksMoment, not the Moment s (AnyMoment ...) thing. The former can be obtained by writing spawnPos <- trimB ... instead of an equal sign =.Mopey
In any case, you seem to have difficulties with juggling forall in general. It's not difficult, but it's not entirely straightforward either. For a basic introduction to the use of forall in dynamic event switching, I recommend my introductory description. Your questions are probably more profound than a simple StackOverflow answer can accommodate for.Mopey
Thank you, I'll read the article. The compiler still expects "Moment t1 a0" instead of "AnyMoment Behavior DSCoord" on the execute line though.Novellanovello

© 2022 - 2024 — McMap. All rights reserved.