RPi4 setup, The Game-Stack

4 Jul 2021

builds: Lander Module
tags: golang

To dev on the RPi 4 I have to first update it:

sudo apt update
df -h # to check disk has enough free space
sudo apt full-upgrade
sudo apt clean

The game stack (tm) requires some careful thinking. I almost want to thread the quit signal all the way down, from main to the game server, to the modal game, to each mode. Because (a) the modalGame Run() can’t block on the mode’s Run(), and (b) we’ll want to wait while a mode finishes Close() before we Setup() the next mode.

So, a Run() needs to return a signal, and be non-blocking. And the selector switch needs to provide a signal for its value changes. And the modalGame’s Run() needs to listen to three signals:

  • quits from above
  • changes from selector
  • dones from below

Something like this:

func (mg *modalGame) Run(quit chan bool) (chan bool, error) {
  done := make(chan bool)

  go func() {
    run := true
    for run{
      select {
        case <-quit:
          mg.Close()
          run = false
          break
        case <-selector.ValueChange():
          mg.closeCurrentMode()
          // start new mode
        case <-mg.currentModeExited:
          // clean up
      }
    }

    done<-true
    close(done)
  }()
}

The overall structure is proofed here: https://play.golang.com/p/EfCbSdv6D3d

Question: do I need games to return a channel for error-forwarding?
Answer: Probably not:

  1. nobody is going to read the logs of this thing (ooh! that gives me an idea though: there should be a button in test mode that prints the logs?! Or will that waste paper?). So it’s reasonable for the game to just log the error and exit 1 or whatever
  2. what would the listener do about it? tell the game to quit? the game should be the one to make that distinction itself

Question: when a mode in the modal game exits organically, what should happen?
Answer: What this means is that someone has completed the mode. They’ve done all the sequences, and gotten a report card. However it happens, the console should be rendered inoperable until the User Switch is reset. In program terms, I think it’s ok for the current modalTest to exit out.

main
  gameServer.PlayUntil(signalCaught)
    modalGame.Run(...)
      listen to changes to the mode selector switch
      testingGame.Run(...)
      launchGame.Run(...)
      landingGame.Run(...)

In the actual program, the testing, launch and landing games will not end of their own accord, but keep listening for a rising edge of the user switch. This behavior allows the user to “reset” their experience, if necessary. (Though perhaps they’d have to hit a kill switch to get the sequence to stop in the first place).

main
  gameServer.PlayUntil(signalCaught)
    modalGame.Run(...)
      listen to changes to the mode selector switch
      testingGame.Run(...)
      launchGame.Run(...)
        listen to changes to the user switch
        launchSequence.Run(...)
      landingGame.Run(...)
        listen to changes to the user switch
        landingSequence.Run(...)

Question: do we even need the games’ Run() to return an exit code? I wonder what kind of runtime (pun intended) error would be catastrophic in that way.
Answer: let’s wait and see, after I do the next level of tests

End of day progress report:
Work continues apace! The modeTest runs, but it has at least one bug :P

  1. I should have an “off mode” handy.

  2. I should try out stubGame.

  3. if I leave testingGame, the listener for the selector stops? All I got was

    go run src/cmd/modeTest/main.go
    game server starting
    selector value changed to 1
    selector value changed to 2
    

    …and that’s it! no more input made any changes. I had to kill the main process and one subprocess to get the gpio back.

First step: more logging.
Well, second step. First step: try to sleep.