Events blocking (Elm 0.13)

83 views
Skip to first unread message

DuctrTape

unread,
Dec 25, 2014, 5:59:16 AM12/25/14
to elm-d...@googlegroups.com
Don't ask why, but for our assignment we have to use Elm 0.13. I run into the following problem when attempting to create a system for easily extending the amount of input signals. 

    data Event = NewGame

               
| PauseGame              

               
| Turn [KeyCode]
                             

               
| PlayerActive [Bool]              

               
| PlayerChanged [PlayerSettings]              

               
| Tick Time          
Geef de code hier op...

One of the states of my game is a "Paused" state, in which I draw a pretty large settings menu. But as soon as this is drawn, all input signals block (even signals that work when the game is started in Playing modus). I'll give a brief overview of my architecture.

Everything that changes in the game should generate a Event:

    data Event = NewGame
               
| PauseGame
               
| Turn [KeyCode]
               
| PlayerActive [Bool]
               
| PlayerChanged [PlayerSettings]
               
| Tick Time


The PlayerChanged event, for example, is generated as follows:

    settingsSignal : Signal Event
    settingsSignal
=
        lift
PlayerChanged <|
             combine
[ pOneSettingsSignal,   pTwoSettingsSignal
                     
, pThreeSettingsSignal, pFourSettingsSignal]
   
    pOneSettingsSignal
: Signal PlayerSettings
    pOneSettingsSignal
=
       
PlayerSettings <~ (Controls <~ lift toCode pOneUp.signal
                                     
~ lift toCode pOneDown.signal
                                     
~ lift toCode pOneLeft.signal
                                     
~ lift toCode pOneRight.signal)
                       
~ (pOneColor.signal)
                       
~ (lift contentToString pOneName.signal)


where pOne<Direction> and pOneColor are inputs for dropDowns and pOneName is an Input for a Input.Field:

    pOneName  : Input Content
    pOneName  
= input (Content nameOne (Selection 0 0 Forward))


I hereby assume that when I update the text field (or a dropdown), a PlayerChanged [PlayerSettings] event will be generated. All event get combined as follows:

    eventSignal : Signal Event
    eventSignal
= merges [ clockSignal
                         
, newGameSignal
                         
, pauseGameSignal
                         
, turnSignal
                         
, activeSignal
                         
, settingsSignal ]


and finally the event signal is lifted onto an update function:

    gameState : Signal Game
    gameState
=
        foldp update initialGame eventSignal
   
    main
= lift2 view gameState Window.dimensions


However, when the game is paused, it seems that all input is blocked and no signals propagate anymore. Also, the text fields are uneditable. Each Input.Field for the player names is defined as follows:

    playerOneName : String -> Element
    playerOneName name
=
        field defaultStyle pOneName
.handle identity nameOne
             
(Content name (Selection 0 0 Forward))


and then, in the view function:

    pOneNameField     = playerOneName   playerOne.settings.name


To me it seems like everything is correct. When editing the displayed field (or any other input), pOneName.signal is changed, which causes (trough a series of liftings) a PlayerChanged event to be generated, which causes the model to be redrawn, which should show the new update. Somehow the Input.Field is still uneditable, however. Worse: even a simple NewGame event isn't generated anymore and events from the dropdowns are also not propagated: nothing changes. 

    newGameSignal : Signal Event
    newGameSignal =
        always NewGame <~   (keepIf identity False <| space)

If I start the game in playing mode (thus no input forms are shown), this works fine and I can reset the game. It seems like the inputs are *blocking* the event stream, but I can't figure out where its going wrong.

Does anyone know what could be causing this problem? 

DuctrTape

unread,
Dec 25, 2014, 6:51:44 AM12/25/14
to elm-d...@googlegroups.com
Update (it gets worse). When I play the game and I finish it, it goes into "Ended" state.

...          
in  if  | length alive == 1 -> { game | state   <- Ended (head alive)
                                     
, players <- collided
                               
}

and now the signals also stop being processed.

The NewGame and PauseGame don't get processed. The (beginning of) the update function looks like this:

update event game =
   
case (event, game.state) of
       
-- Reset positions and orientations and begin playing.
       
(NewGame, _) ->
           
...
       
(PauseGame, _)->
           
...

So I'd think regardless of state these event should get processed. But they don't. 

I honestly have no idea what's going on. If anyone thinks they can help me if they have acces to the full code, feel free to contact me.

PS: It seems like the markup in the beginning of the initial message got screwed up. Sorry for that.


Op donderdag 25 december 2014 11:59:16 UTC+1 schreef DuctrTape:

Jeff Smits

unread,
Dec 25, 2014, 8:40:18 AM12/25/14
to elm-discuss
To debug this I'd need some executable Elm code that exhibits this problematic behaviour. Can you cut down your program into something small but still showing the problem? 
One of the things I'd look into is the eventSignal, to see if any events come at exactly the same time, which would force merges to drop some events. You can use Debug.log for that. 

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Evan Czaplicki

unread,
Dec 25, 2014, 6:19:24 PM12/25/14
to elm-d...@googlegroups.com
I second Jeff's advice. If you can cut it down to the bare minimum in a gist, it'll be much easier to help. Also, adding Debug.log and if you want to log deeper stuff, generating JS and adding in console.log statements.

DuctrTape

unread,
Dec 26, 2014, 4:41:28 AM12/26/14
to elm-d...@googlegroups.com
So yesterday, half an hour past the deadline, I fixed it. 

Appeaantly the 

case (event, game.state) of
   
(NewGame, _) ->
   
...
   
(Tick t, Playing) ->

blocks if the pattern can't be matched, so the Tick events sent in Paused or Ended Player states blocked the function, causing the game to stop. Adding a simple

     (_, _) -> game

solved everything and the game worked right away.

Thanks anyway!

Reply all
Reply to author
Forward
0 new messages