Fixing up MainLoop

A project log for Raspberry Pi Hue/Nanoleaf Light Switch

Light control for rooms containing both Philips Hue and Nanoleaf lights using their respective REST APIs

Tim SchonbergerTim Schonberger 04/09/2020 at 15:100 Comments

Looking at the code, I felt like it was odd that the entire application was forever tied to a PyGame loop. For an actual game where elements need to update regularly, but for this application, the screen really only needs to update when input occurs. 

Before, this is what was happening:

A PyGame loop was running, constantly checking for input and rendering the state of the application. For running this on the desktop, this made sense, since PyGame was the easiest way to get a display and input working. However, on a Raspberry Pi, this loop is kind of wasteful since we're not running a window or using a keyboard.

I decided to take another approach that looks less like a game loop.

Instead, MainLoop became not a loop at all. All it really does now is set up the rendering, and then adds a callback to the input class. Whenever an input event occurs, it executes the callback when then triggers the draw function in the renderer. This way, the entire application isn't tied to any particular loop, and the screen only gets redrawn when an input event happens.

This being said, there are still two separate implementations of the input class.

RPi.GPIO luckily has the ability to set up callbacks. When a pin's state changes, it calls a callback that interprets the pin as a button, and then the input class calls the input callback in main loop and passes that button so the button can actually be handled.

The PyGame input implementation still does operate on a loop to check for input events. It interprets the events into logical buttons, and then calls the input callback manually.

This way, PyGame is only used when the application is run on the desktop, so when running on the Pi, we don't need to worry about a loop running constantly. Instead, we just block the application in the input class with

input('\nPress any key to exit.\n')