Processing input events with LuaSDL

LuaSDL offers a form of platform-independent abstraction layer to these devices with an inner event pool. You only have to query the event pool for unprocessed events and, if there are any, check for the event type.

Getting ready

Before doing any event processing, your application must initialize internal event pools. This can be achieved with the SDL.SDL_Init function, where the only parameter is a bitmask representing which parts of LuaSDL you want to initialize. You can use the bitlib library for the Lua language. Another option would be to use the bit32 internal library if you are using the newer version of the Lua interpreter. The default value here is SDL.SDL_INIT_EVERYTHING, which is fine as it starts the event pool automatically. Specifically, you can use the SDL.SDL_INIT_EVENTTHREAD or SDL.SDL_INIT_VIDEO values to initialize the event pool.

A code sample can be used to initialize the LuaSDL library. It should be used right at the start of the application:

require 'LuaSDL'
require 'bit'
-- initialize video device and internal thread for event processing
SDL.SDL_Init(bit.bor(SDL.SDL_INIT_VIDEO, SDL.SDL_INIT_EVENTTHREAD))

How to do it…

You can poll for currently pending events with the SDL.SDL_PollEvent function. This function uses the SDL_Event object as the only argument and fills this object with event information, if there's any. LuaSDL provides the SDL.SDL_Event_local function, which creates the local SDL_Event object. Keep in mind that this object is not kept globally. The SDL_Event object will be subject to garbage collection after you leave the block where it was defined. The SDL.SDL_PollEvent function also returns a value 1 if there is an event that is currently pending or 0 if there aren't any. This approach is quite desirable because you call this function only once for each event loop iteration. If there are no events pending, you can just skip further event processing in that iteration.

First of all, you need to create a local event object. This object will contain event information and can be defined at the start of your application and freed upon application exit.

local event = SDL.SDL_Event_local()

The application event loop can be defined as a while loop:

local running = true
while (running) do
  if (SDL.SDL_PollEvent(event) ~= 0) then
    process_event(event)
  end
end

Incoming events will be processed in the process_event function. This function usually handles more than one type of event, which is defined in the event.type variable. Each event type can be processed separately inside the if-then-else chain of code blocks or you can rely on the function map stored in a Lua table in the form of an associative array. The Lua language doesn't contain the switch statement known from other programming languages, so you are mostly left with these two options. For other kinds of switch statement alternatives, you can refer to the lua-users wiki page at http://lua-users.org/wiki/SwitchStatement.

As long as the amount of event types is small enough, it doesn't really matter which one you use.

Event handling with the if-then-else chain

An example of the if-else-if chain is shown in the following code:

local function process_event(event)
  if event.type == SDL.SDL_KEYDOWN then
    print("Key pressed:", event.key.keysym.sym)
  elseif event.type == SDL.SDL_KEYUP then
    print("Key released:", event.key.keysym.sym)
  elseif event.type == SDL.SDL_QUIT
    running = false
  end
end

In the first case with event type SDL.SDL_KEY_DOWN, the code captures an event of pressing a key on your keyboard. You can get both the key symbol code defined in event.key.keysym.sym or a scan code from event.key.keysym.scancode. A key symbol code is keyboard-layout dependent, whereas scancode is a hardware-dependent value. Usually, you'll want to use a key symbol code if you're developing a game.

The second case with the SDL.SDL_KEYUP event type captures an event of key releasing and the last one detects a quit event when the user closes the application window.

Event handling with an associative array

The next example shows how to process events with the associative array represented with the Lua table:

local events = {
  [SDL.SDL_KEYDOWN] = function(raw_event)
    local event = raw_event.key
    local key = event.keysym.sym
    print("Key pressed:", key)
  end,
  [SDL.SDL_KEYUP] = function(raw_event)
    local event = raw_event.key
    local key = event.keysym.sym
       print("Key released:", key)
  end,
  [SDL.SDL_QUIT] = function(raw_event)
    running = false
  end,
}
local function process_event(event)
  local event_fn = events[event.type]
  if type(event_fn)=='function' then
    event_fn(event)
  end
end

In this case, the process_event function looks up for a key-value pair in the events table. A key part of a pair corresponds to the event type identifier. On the other hand, a value part contains a function that will be invoked. A complete list of valid event type identifiers is shown in a table, which we will look at shortly. In every case, an event function will be called with the current event object placed in the first function argument.

Keep in mind that LuaSDL always uses a generic form of event object. Therefore, to get a certain event attribute, you need to follow this structure:

event.[structure_name].[structure_attribute]

For instance, if you wanted to know what key was pressed, you can use the key symbol identifier from the key structure.

local keySymbol = event.key.keysym.sym

The following table shows what event types LuaSDL can handle:

Event types

Description

Structure names

Structure attributes

SDL_ACTIVEEVENT

This allows you to gain or lose window focus

Active

gain state

SDL_KEYDOWN

This allows you to press down a key on the keyboard

Key

state keysym

SDL_KEYUP

This allows you to release a key on the keyboard

SDL_MOUSEMOTION

This enables mouse movement over the application window

Motion

state

x,y

srel, yrel

SDL_MOUSEBUTTONDOWN

This enables pressing a mouse button

Button

which

button

state

x, y

SDL_MOUSEBUTTONUP

This enables releasing a mouse button

SDL_JOYAXISMOTION

This enables joystick movement

jaxis

which

axis

value

SDL_JOYBUTTONDOWN

This enables you to press a joystick button

jbutton

which

button

state

SDL_JOYBUTTONUP

This enables you to release a joystick button

SDL_JOYHATMOTION

This enables the joystick to change the hat position

jhat

which

hat

value

SDL_JOYBALLMOTION

This enables the joystick to change the trackball movement

jball

which

ball

xrel, yrel

SDL_VIDEORESIZE

This enables the window to resize

resize

w,h

SDL_VIDEOEXPOSE

This enables screen redraw

Not applicable

SDL_SYSWMEVENT

This is a platform-dependent event

syswm

msg

SDL_USEREVENT

This is a user-defined event

User

code

data1, data2

SDL_QUIT

This means that quit was requested

Not applicable

Each event type has its own attributes. You can use those attributes to obtain information about specific events, for example, the mouse button that was pressed or the key symbol code. The next set of recipes in this chapter will cover the most common use cases of some of the event types.

How it works…

The LuaSDL library is intended to be used with the event polling mechanism, which is used in a loop, as you can see in the following sample code:

-- application can be exited be setting running variable to false
local running = true
-- prepare local instance of SDL_Event object
local local_event = SDL.SDL_Event_local()

while (running) do
  -- check for events in the poll
  if (SDL.SDL_PollEvent(local_event)~=0) then
    local event_fn = events[local_event.type]
    if type(event_fn)=='function' then
      event_fn(local_event)
    end
  else
    -- ...do game mechanics
  end
end

This application design allows you to react to the input event when needed while idle time can be used to process game mechanics or video rendering. However, special care must be taken to prevent game mechanics from taking too long to finish as this may halt your application or make it less responsive.

See also

  • The Using the keyboard input recipe
  • The Using the relative mouse position recipe
  • The Using the absolute mouse position recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.255.87