Skip to content

1.4 handlers

Lothar Thole edited this page Aug 20, 2024 · 3 revisions

Handlers in Lua

The term "handler" will be familiar to programmers. For those who may not immediately understand what it means, here is a "beginner's explanation": A handler in Ethos Lua can be thought of as a kind of program module. In principle, a handler is a program routine that is started due to an overarching (system) event.


There are various "specialized" modules/handlers for different tasks, or for different "events"/triggers, such as:


• Transmitter start (initialization)
• First call
• Touch event
• Configuration adjustment...

Each module has a fixed name, an overview of the handlers is listed below. Each module, each handler, executes a self-contained routine corresponding to its task through the program sequence it contains. The "data exchange" between the handlers, if desired, takes place via a uniform data structure, e.g., named "widget." This data structure is appropriately generated during the first call (by the create handler).


Below is a brief explanation of the individual handlers. More detailed functionality will be illustrated by example scripts included in the individual chapters.




List of typical Handlers


init()

This handler is called during the transmitter's boot process.

The handler is used to provide the transmitter with a list of all Lua scripts with their unique "keys" (unique identifiers) and their types (widget, systemTool, etc.). The "environment" (i.e. which handlers exist in the script) is also set up in the process.

Code Example:


local function init()
    system.registerWidget({key="GV1", name="GVinflight", create=create, paint=paint, wakeup=wakeup, configure=configure, title=false, read=read, write=write})
end



create()

The create handler is executed the first time the script is called, for example, when the screen of a widget is activated for the first time. In the create handler, the "central data structure" or an array is typically defined, which can be passed to other handlers. This data structure must be defined as the return value of the handler. Often (e.g., in a widget), this is named as widget.



wakeup(widget)

The wakeup handler is the general background handler for all kinds of tasks (all tasks except those handled by the handlers listed below). This usually includes reading sources such as switch positions, analog inputs, telemetry values, their processing, and updating the central data structure (principle: input, processing, output). It is generally called around a dozen times per second. Another essential element is to decide whether data relevant to the display (in the paint handler) has changed. If so, the wakeup handler triggers an update of the display using the method lcd.invalidate(). Ideally (for performance reasons), the area to be updated is specified. Multiple areas can be specified in a single wakeup run.



paint(widget)

The paint handler is responsible for graphical representations in a script. It is therefore only necessary in scripts that display something on the screen, such as widgets and system scripts, but not source scripts. Only here do the methods/functions for drawing, text, and value display (lcd class) have relevance. Ideally, the wakeup handler has pre-processed all necessary texts, values, and other variables, so that almost only presentation-relevant program blocks are present here.

Note: In forums, there are often misunderstandings about the interaction of the wakeup handler, the paint handler, and the lcd.invalidate() method. In general, it should be understood as follows:

• wakeup is responsible for general background processing and, as far as possible, for pre-processing the data used in paint. Wakeup is called very frequently by the system.

• paint is also frequently called by the system, "following" the wakeup handler. The focus is on graphical presentation. VERY IMPORTANT: Calling a graphical method such as drawing lines, "printing" texts or values, etc., does NOT necessarily mean that this will also be directly displayed on the screen; it initially fills a very fast image buffer.

• lcd.invalidate(x,y,w,h): Only this call causes the screen (or the specified area) to be cleared and the relatively "slow" screen memory to be filled with new data. The method should only be called from wakeup, ideally when it has been determined that something in the display has been updated!

The fact that the execution of paint does not necessarily lead to a screen refresh can be confusing for beginners but has significant performance advantages for the entire system.



event(widget, category, value, x, y)

This handler is used to process "external events," usually user interventions. For example, touching a screen, pressing control buttons (Page Up/Down), scroll wheel, etc. As seen above, in addition to the typical "widget" structure, Ethos also passes the category (e.g., touch event), the value (press/release), and coordinates as input parameters.



configure(widget)

Those who have already worked with widgets may be familiar with the option to configure them via a menu call. This call triggers the config handler. In particular, there are options available to design an extensive config menu via the forms class.



write(widget)

The write handler saves model-specific parameters to the model file. Typically, changes in values in the config handler trigger this write action. Of course, the handler must have already been defined by the init handler. (-;



read(widget)

The parameters written by the write handler should, of course, also be loaded when the model is loaded (or otherwise). This is done by the read handler.



menu(widget)

Handler that is called when creating a context menu to allow adding additional options.



close(widget)

Handler that is called when the current page is closed.





Flowchart (handler)

To roughly illustrate the flow, a small graphic showing when the handlers are called:

image

It also becomes apparent that the screen display is only refreshed by the call to the lcd.invalidate() method.

The wakeup handler should always check whether something on the display has changed (values, etc.) and only then trigger the resource-intensive refresh with lcd.invalidate().

(By the way, during the very first widget call, Ethos also refreshes the display itself.)

Clone this wiki locally