Created
December 8, 2017 07:46
-
-
Save cipharius/adf3323a512023727193c2c65582bf90 to your computer and use it in GitHub Desktop.
Keyboard input actions for SDL2 on Nim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import strutils | |
import sdl2 | |
type | |
ListenerPtr = proc (action: Action) {.closure.} | |
Action* = ref object | |
active: bool | |
kind: string | |
keysyms: seq[cint] | |
listeners: seq[ListenerPtr] | |
Listener = ref object | |
procedure: ListenerPtr | |
action: Action | |
OccupiedException = object of Exception | |
## Raised if object is already taken | |
var actions: seq[Action] = @[] | |
# Action methods | |
method addListener*(this: Action, listener: ListenerPtr): Listener {.discardable,base.} = | |
## Add action listener procedure | |
this.listeners.add listener | |
result = Listener(procedure: listener, action: this) | |
method bindKey*(this: Action, key: cint) {.base.} = | |
## Add a new action keybinding | |
this.keysyms.add key | |
method unbindKey*(this: Action, key: cint) {.base.} = | |
## Unbind key from action | |
for i, k in this.keysyms: | |
if k == key: | |
this.keysyms.delete i | |
break | |
method kind*(this: Action): string {.base.} = this.kind | |
method `$`*(this: Action): string {.base.} = this.kind | |
method isActive*(this: Action): bool {.base.} = this.active | |
proc setState(this: Action, state: bool) = | |
this.active = state | |
for listener in this.listeners: | |
listener(this) | |
# Listener methods | |
method disconnect*(this: Listener) {.base.} = | |
## Disconnect listener from it's action | |
for i,listener in this.action.listeners: | |
if listener == this.procedure: | |
this.action.listeners.delete i | |
break | |
# Generic procedures | |
proc registerAction*(kind: string): Action {.discardable.} = | |
## Registers a new action | |
# Check if action is already registered | |
for action in actions: | |
if action.kind == kind: | |
raise newException(OccupiedException, "Duplicate action \"$#\"" % kind) | |
result = Action(kind: kind, active: false, listeners: @[], keysyms: @[]) | |
actions.add result | |
proc handleInput*(event: KeyboardEventPtr) = | |
for action in actions: | |
for keysym in action.keysyms: | |
if event.keysym.sym == keysym: | |
action.setState event.state == KeyPressed.uint8 | |
proc getAction*(kind: string): Action = | |
## Retrieve already registered action | |
for action in actions: | |
if action.kind == kind: | |
return action | |
return nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment