Nim! pt5



In my last post I showed how to get a circle bouncing back and forth on the screen. Next, I’d need to figure out how Nim handles SDL_Event, which normally uses a union structure along with a type field to determine how the data for an event gets used.

Nim doesn’t have a union type as far as I can tell. It has a pragma for telling the compiler that a Nim structure should be translated to a C union, but that’s not what I"m looking for.

Digging into the SDL2 wrapper a little, I think this is the piece of code I need to understand:

template EvConv(name, name2, ptype: expr; valid: set[TEventType]): stmt {.immediate.}=
  proc `name`* (event: var TEvent): ptype =
    assert event.kind in valid
    return cast[ptype](addr event)
  proc `name2`* (event: var TEvent): ptype =
    assert event.kind in valid
    return cast[ptype](addr event)

which is used like:

EvConv(EvWindow, window, PWindowEvent, {WindowEvent})

What is a template in Nim’s parlance? As it turns out, it’s a way of creating a simple substitution macro at compile time, and is called like a normal procedure.

Therefore the EvConv template being defined above is creating 2 procedures that are identical, except for the name. If you direct your gaze to the usage example, the first two parameters are EvWindow and window – which means that the example will result in two procedures called EvWindow and window, which do precisly the same thing, which is to make certain the kind of event is a valid kind, and then to cast (reinterpret the type without altering the bit structure) the event data into the Nim type pointed to by the ptype pointer.

The result of this is that in my program I can check for a keydown event thusly:

    if evt.kind == KeyDown:
      if evt.key.keysym.sym == K_ESCAPE:
        runGame = false

There’s a few things that initially tripped me up with even that, so allow me to explain a few more things:


That still wasn’t much code, but I did learn a lot about the SDL2 wrapper, Nim, and even a little about SDL2 itself!