Scripting: Add base input, supports key events

This commit is contained in:
Vicki Pfau 2023-01-02 01:05:41 -08:00
parent fcfab847fc
commit e5ed2b4119
4 changed files with 554 additions and 0 deletions

217
include/mgba/script/input.h Normal file
View File

@ -0,0 +1,217 @@
/* Copyright (c) 2013-2022 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef M_SCRIPT_INPUT_H
#define M_SCRIPT_INPUT_H
#include <mgba-util/common.h>
#include <mgba/script/context.h>
#include <mgba/script/macros.h>
CXX_GUARD_START
enum mScriptEventType {
mSCRIPT_EV_TYPE_NONE = 0,
mSCRIPT_EV_TYPE_KEY,
mSCRIPT_EV_TYPE_MOUSE_BUTTON,
mSCRIPT_EV_TYPE_MOUSE_MOVE,
mSCRIPT_EV_TYPE_MOUSE_WHEEL,
mSCRIPT_EV_TYPE_GAMEPAD_BUTTON,
mSCRIPT_EV_TYPE_GAMEPAD_HAT,
mSCRIPT_EV_TYPE_TRIGGER,
mSCRIPT_EV_TYPE_MAX
};
enum mScriptInputState {
mSCRIPT_INPUT_STATE_UP = 0,
mSCRIPT_INPUT_STATE_DOWN = 1,
mSCRIPT_INPUT_STATE_HELD = 2,
};
enum mScriptInputDirection {
mSCRIPT_INPUT_DIR_NONE = 0,
mSCRIPT_INPUT_DIR_NORTH = 1,
mSCRIPT_INPUT_DIR_EAST = 2,
mSCRIPT_INPUT_DIR_SOUTH = 4,
mSCRIPT_INPUT_DIR_WEST = 8,
mSCRIPT_INPUT_DIR_UP = mSCRIPT_INPUT_DIR_NORTH,
mSCRIPT_INPUT_DIR_RIGHT = mSCRIPT_INPUT_DIR_EAST,
mSCRIPT_INPUT_DIR_DOWN = mSCRIPT_INPUT_DIR_SOUTH,
mSCRIPT_INPUT_DIR_LEFT = mSCRIPT_INPUT_DIR_WEST,
mSCRIPT_INPUT_DIR_NORTHEAST = mSCRIPT_INPUT_DIR_NORTH | mSCRIPT_INPUT_DIR_EAST,
mSCRIPT_INPUT_DIR_NORTHWEST = mSCRIPT_INPUT_DIR_NORTH | mSCRIPT_INPUT_DIR_WEST,
mSCRIPT_INPUT_DIR_SOUTHEAST = mSCRIPT_INPUT_DIR_SOUTH | mSCRIPT_INPUT_DIR_EAST,
mSCRIPT_INPUT_DIR_SOUTHWEST = mSCRIPT_INPUT_DIR_SOUTH | mSCRIPT_INPUT_DIR_WEST,
};
enum mScriptKeyModifier {
mSCRIPT_KMOD_NONE = 0,
mSCRIPT_KMOD_LSHIFT = 0x1,
mSCRIPT_KMOD_RSHIFT = 0x2,
mSCRIPT_KMOD_SHIFT = 0x3,
mSCRIPT_KMOD_LCONTROL = 0x4,
mSCRIPT_KMOD_RCONTROL = 0x8,
mSCRIPT_KMOD_CONTROL = 0xC,
mSCRIPT_KMOD_LALT = 0x10,
mSCRIPT_KMOD_RALT = 0x20,
mSCRIPT_KMOD_ALT = 0x30,
mSCRIPT_KMOD_LSUPER = 0x40,
mSCRIPT_KMOD_RSUPER = 0x80,
mSCRIPT_KMOD_SUPER = 0xC0,
mSCRIPT_KMOD_CAPS_LOCK = 0x100,
mSCRIPT_KMOD_NUM_LOCK = 0x200,
mSCRIPT_KMOD_SCROLL_LOCK = 0x400,
};
#define mSCRIPT_KEYBASE 0x200000
enum mScriptKey {
mSCRIPT_KEY_NONE = 0,
mSCRIPT_KEY_BACKSPACE = 0x000008,
mSCRIPT_KEY_TAB = 0x000009,
mSCRIPT_KEY_LINE_FEED = 0x00000A,
mSCRIPT_KEY_ESCAPE = 0x00001B,
mSCRIPT_KEY_DELETE = 0x00007F,
mSCRIPT_KEY_F1 = mSCRIPT_KEYBASE | 1,
mSCRIPT_KEY_F2,
mSCRIPT_KEY_F3,
mSCRIPT_KEY_F4,
mSCRIPT_KEY_F5,
mSCRIPT_KEY_F6,
mSCRIPT_KEY_F7,
mSCRIPT_KEY_F8,
mSCRIPT_KEY_F9,
mSCRIPT_KEY_F10,
mSCRIPT_KEY_F11,
mSCRIPT_KEY_F12,
mSCRIPT_KEY_F13,
mSCRIPT_KEY_F14,
mSCRIPT_KEY_F15,
mSCRIPT_KEY_F16,
mSCRIPT_KEY_F17,
mSCRIPT_KEY_F18,
mSCRIPT_KEY_F19,
mSCRIPT_KEY_F20,
mSCRIPT_KEY_F21,
mSCRIPT_KEY_F22,
mSCRIPT_KEY_F23,
mSCRIPT_KEY_F24,
mSCRIPT_KEY_UP = mSCRIPT_KEYBASE | 0x20,
mSCRIPT_KEY_RIGHT,
mSCRIPT_KEY_DOWN,
mSCRIPT_KEY_LEFT,
mSCRIPT_KEY_PAGE_UP,
mSCRIPT_KEY_PAGE_DOWN,
mSCRIPT_KEY_HOME,
mSCRIPT_KEY_END,
mSCRIPT_KEY_INSERT,
mSCRIPT_KEY_BREAK,
mSCRIPT_KEY_CLEAR,
mSCRIPT_KEY_PRNTSCR,
mSCRIPT_KEY_SYSRQ,
mSCRIPT_KEY_MENU,
mSCRIPT_KEY_LSHIFT = mSCRIPT_KEYBASE | 0x30,
mSCRIPT_KEY_RSHIFT,
mSCRIPT_KEY_SHIFT,
mSCRIPT_KEY_LCONTROL,
mSCRIPT_KEY_RCONTROL,
mSCRIPT_KEY_CONTROL,
mSCRIPT_KEY_LALT,
mSCRIPT_KEY_RALT,
mSCRIPT_KEY_ALT,
mSCRIPT_KEY_LSUPER,
mSCRIPT_KEY_RSUPER,
mSCRIPT_KEY_SUPER,
mSCRIPT_KEY_CAPS_LOCK,
mSCRIPT_KEY_NUM_LOCK,
mSCRIPT_KEY_SCROLL_LOCK,
};
struct mScriptEvent {
int32_t type;
int32_t reserved;
uint64_t seq;
};
struct mScriptKeyEvent {
struct mScriptEvent d;
uint8_t state;
uint8_t reserved;
uint16_t modifiers;
uint32_t key;
};
struct mScriptMouseButtonEvent {
struct mScriptEvent d;
uint8_t state;
uint8_t mouse;
uint8_t button;
};
struct mScriptMouseMoveEvent {
struct mScriptEvent d;
bool relative;
uint8_t mouse;
int32_t x;
int32_t y;
};
struct mScriptMouseWheelEvent {
struct mScriptEvent d;
uint8_t mouse;
int32_t x;
int32_t y;
};
struct mScriptGamepadButtonEvent {
struct mScriptEvent d;
uint8_t state;
uint8_t pad;
uint16_t button;
};
struct mScriptGamepadHatEvent {
struct mScriptEvent d;
uint8_t pad;
uint8_t hat;
uint8_t direction;
};
struct mScriptTriggerEvent {
struct mScriptEvent d;
uint8_t trigger;
bool state;
};
mSCRIPT_DECLARE_STRUCT(mScriptEvent);
mSCRIPT_DECLARE_STRUCT(mScriptKeyEvent);
mSCRIPT_DECLARE_STRUCT(mScriptMouseButtonEvent);
mSCRIPT_DECLARE_STRUCT(mScriptMouseMoveEvent);
mSCRIPT_DECLARE_STRUCT(mScriptMouseWheelEvent);
mSCRIPT_DECLARE_STRUCT(mScriptGamepadButtonEvent);
mSCRIPT_DECLARE_STRUCT(mScriptGamepadHatEvent);
mSCRIPT_DECLARE_STRUCT(mScriptSensorEvent);
mSCRIPT_DECLARE_STRUCT(mScriptTriggerEvent);
void mScriptContextAttachInput(struct mScriptContext* context);
void mScriptContextFireEvent(struct mScriptContext*, struct mScriptEvent*);
CXX_GUARD_END
#endif

View File

@ -1,6 +1,7 @@
include(ExportDirectory)
set(SOURCE_FILES
context.c
input.c
socket.c
stdlib.c
types.c)
@ -13,6 +14,7 @@ if(USE_LUA)
list(APPEND SOURCE_FILES engines/lua.c)
list(APPEND TEST_FILES
test/context.c
test/input.c
test/lua.c
test/stdlib.c)
endif()

249
src/script/input.c Normal file
View File

@ -0,0 +1,249 @@
/* Copyright (c) 2013-2022 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/script/input.h>
#include <mgba-util/string.h>
#include <mgba-util/table.h>
static const char* eventNames[mSCRIPT_EV_TYPE_MAX] = {
[mSCRIPT_EV_TYPE_KEY] = "key",
[mSCRIPT_EV_TYPE_MOUSE_BUTTON] = "mouseButton",
[mSCRIPT_EV_TYPE_MOUSE_MOVE] = "mouseMove",
[mSCRIPT_EV_TYPE_MOUSE_WHEEL] = "mouseWheel",
[mSCRIPT_EV_TYPE_GAMEPAD_BUTTON] = "gamepadButton",
[mSCRIPT_EV_TYPE_GAMEPAD_HAT] = "gamepadHat",
[mSCRIPT_EV_TYPE_TRIGGER] = "trigger",
};
static const struct mScriptType* eventTypes[mSCRIPT_EV_TYPE_MAX] = {
[mSCRIPT_EV_TYPE_KEY] = mSCRIPT_TYPE_MS_S(mScriptKeyEvent),
[mSCRIPT_EV_TYPE_MOUSE_BUTTON] = mSCRIPT_TYPE_MS_S(mScriptMouseButtonEvent),
[mSCRIPT_EV_TYPE_MOUSE_MOVE] = mSCRIPT_TYPE_MS_S(mScriptMouseMoveEvent),
[mSCRIPT_EV_TYPE_MOUSE_WHEEL] = mSCRIPT_TYPE_MS_S(mScriptMouseWheelEvent),
[mSCRIPT_EV_TYPE_GAMEPAD_BUTTON] = mSCRIPT_TYPE_MS_S(mScriptGamepadButtonEvent),
[mSCRIPT_EV_TYPE_GAMEPAD_HAT] = mSCRIPT_TYPE_MS_S(mScriptGamepadHatEvent),
};
struct mScriptInputContext {
struct Table activeKeys;
};
static void _mScriptInputDeinit(struct mScriptInputContext*);
static bool _mScriptInputIsKeyActive(const struct mScriptInputContext*, struct mScriptValue*);
mSCRIPT_DECLARE_STRUCT(mScriptInputContext);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptInputContext, _deinit, _mScriptInputDeinit, 0);
mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActive, _mScriptInputIsKeyActive, 1, WRAPPER, key);
mSCRIPT_DEFINE_STRUCT(mScriptInputContext)
mSCRIPT_DEFINE_STRUCT_DEINIT(mScriptInputContext)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, isKeyActive)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptEvent, S32, type)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptEvent, U64, seq)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptKeyEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptKeyEvent, U8, state)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptKeyEvent, S16, modifiers)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptKeyEvent, S32, key)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptMouseButtonEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseButtonEvent, U8, mouse)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseButtonEvent, U8, state)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseButtonEvent, U8, button)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptMouseMoveEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseMoveEvent, U8, mouse)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseMoveEvent, S32, x)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseMoveEvent, S32, y)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptMouseWheelEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseWheelEvent, U8, mouse)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseWheelEvent, S32, x)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptMouseWheelEvent, S32, y)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptGamepadButtonEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadButtonEvent, U8, state)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadButtonEvent, U8, pad)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadButtonEvent, U16, button)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(mScriptGamepadHatEvent)
mSCRIPT_DEFINE_INHERIT(mScriptEvent)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadHatEvent, U8, pad)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadHatEvent, U8, hat)
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptGamepadHatEvent, U8, direction)
mSCRIPT_DEFINE_END;
void mScriptContextAttachInput(struct mScriptContext* context) {
struct mScriptInputContext* inputContext = calloc(1, sizeof(*inputContext));
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptInputContext));
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
value->value.opaque = inputContext;
TableInit(&inputContext->activeKeys, 0, NULL);
mScriptContextSetGlobal(context, "input", value);
mScriptContextSetDocstring(context, "input", "Singleton instance of struct::mScriptInputContext");
mScriptContextExportConstants(context, "EV_TYPE", (struct mScriptKVPair[]) {
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, NONE),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, KEY),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, MOUSE_BUTTON),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, MOUSE_MOVE),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, MOUSE_WHEEL),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, GAMEPAD_BUTTON),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_EV_TYPE, TRIGGER),
mSCRIPT_KV_SENTINEL
});
mScriptContextExportConstants(context, "INPUT_STATE", (struct mScriptKVPair[]) {
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_STATE, UP),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_STATE, DOWN),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_STATE, HELD),
mSCRIPT_KV_SENTINEL
});
mScriptContextExportConstants(context, "INPUT_DIR", (struct mScriptKVPair[]) {
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, NONE),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, NORTH),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, EAST),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, SOUTH),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, WEST),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, UP),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, RIGHT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, DOWN),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, LEFT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, NORTHEAST),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, NORTHWEST),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, SOUTHEAST),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_INPUT_DIR, SOUTHWEST),
mSCRIPT_KV_SENTINEL
});
mScriptContextExportConstants(context, "KMOD", (struct mScriptKVPair[]) {
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, NONE),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, LSHIFT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, RSHIFT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, SHIFT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, LCONTROL),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, RCONTROL),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, CONTROL),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, LALT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, RALT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, ALT),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, LSUPER),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, RSUPER),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, SUPER),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, CAPS_LOCK),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, NUM_LOCK),
mSCRIPT_CONSTANT_PAIR(mSCRIPT_KMOD, SCROLL_LOCK),
mSCRIPT_KV_SENTINEL
});
}
void _mScriptInputDeinit(struct mScriptInputContext* context) {
TableDeinit(&context->activeKeys);
}
bool _mScriptInputIsKeyActive(const struct mScriptInputContext* context, struct mScriptValue* value) {
uint32_t key;
struct mScriptValue intValue;
size_t length;
const char* strbuf;
switch (value->type->base) {
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_UINT:
case mSCRIPT_TYPE_FLOAT:
if (!mScriptCast(mSCRIPT_TYPE_MS_U32, value, &intValue)) {
return false;
}
key = intValue.value.u32;
break;
case mSCRIPT_TYPE_STRING:
if (value->value.string->length > 1) {
return false;
}
strbuf = value->value.string->buffer;
length = value->value.string->size;
key = utf8Char(&strbuf, &length);
break;
default:
return false;
}
void* down = TableLookup(&context->activeKeys, key);
return down != NULL;
}
static bool _updateKeys(struct mScriptContext* context, struct mScriptKeyEvent* event) {
int offset = 0;
switch (event->state) {
case mSCRIPT_INPUT_STATE_UP:
offset = -1;
break;
case mSCRIPT_INPUT_STATE_DOWN:
offset = 1;
break;
default:
return true;
}
struct mScriptValue* input = mScriptContextGetGlobal(context, "input");
if (!input) {
return false;
}
struct mScriptInputContext* inputContext = input->value.opaque;
intptr_t value = (intptr_t) TableLookup(&inputContext->activeKeys, event->key);
value += offset;
if (value < 1) {
TableRemove(&inputContext->activeKeys, event->key);
} else {
TableInsert(&inputContext->activeKeys, event->key, (void*) value);
}
if (offset < 0 && value > 0) {
return false;
}
if (offset > 0 && value != 1) {
event->state = mSCRIPT_INPUT_STATE_HELD;
}
return true;
}
void mScriptContextFireEvent(struct mScriptContext* context, struct mScriptEvent* event) {
switch (event->type) {
case mSCRIPT_EV_TYPE_KEY:
if (!_updateKeys(context, (struct mScriptKeyEvent*) event)) {
return;
}
break;
case mSCRIPT_EV_TYPE_NONE:
return;
}
struct mScriptList args;
mScriptListInit(&args, 1);
struct mScriptValue* value = mScriptListAppend(&args);
value->type = eventTypes[event->type];
value->refs = mSCRIPT_VALUE_UNREF;
value->flags = 0;
value->value.opaque = event;
mScriptContextTriggerCallback(context, eventNames[event->type], &args);
mScriptListDeinit(&args);
}

86
src/script/test/input.c Normal file
View File

@ -0,0 +1,86 @@
/* Copyright (c) 2013-2022 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "util/test/suite.h"
#include <mgba/internal/script/lua.h>
#include <mgba/script/context.h>
#include <mgba/script/input.h>
#include <mgba/script/types.h>
#include "script/test.h"
#define SETUP_LUA \
struct mScriptContext context; \
mScriptContextInit(&context); \
struct mScriptEngineContext* lua = mScriptContextRegisterEngine(&context, mSCRIPT_ENGINE_LUA); \
mScriptContextAttachStdlib(&context); \
mScriptContextAttachInput(&context)
M_TEST_SUITE_SETUP(mScriptInput) {
if (mSCRIPT_ENGINE_LUA->init) {
mSCRIPT_ENGINE_LUA->init(mSCRIPT_ENGINE_LUA);
}
return 0;
}
M_TEST_SUITE_TEARDOWN(mScriptInput) {
if (mSCRIPT_ENGINE_LUA->deinit) {
mSCRIPT_ENGINE_LUA->deinit(mSCRIPT_ENGINE_LUA);
}
return 0;
}
M_TEST_DEFINE(members) {
SETUP_LUA;
TEST_PROGRAM("assert(input)");
TEST_PROGRAM("assert(input.isKeyActive)");
mScriptContextDeinit(&context);
}
M_TEST_DEFINE(fireKey) {
SETUP_LUA;
TEST_PROGRAM("assert(not input:isKeyActive('a'))");
TEST_PROGRAM(
"activeKey = false\n"
"state = nil\n"
"function cb(ev)\n"
" assert(ev.type == C.EV_TYPE.KEY)\n"
" activeKey = string.char(ev.key)\n"
" state = ev.state\n"
"end\n"
"id = callbacks:add('key', cb)\n"
"assert(id)\n"
"assert(not activeKey)\n"
);
struct mScriptKeyEvent keyEvent = {
.d = { .type = mSCRIPT_EV_TYPE_KEY },
.state = mSCRIPT_INPUT_STATE_DOWN,
.key = 'a'
};
mScriptContextFireEvent(&context, &keyEvent.d);
TEST_PROGRAM("assert(input:isKeyActive('a'))");
TEST_PROGRAM("assert(activeKey == 'a')");
TEST_PROGRAM("assert(state == C.INPUT_STATE.DOWN)");
keyEvent.state = mSCRIPT_INPUT_STATE_UP;
mScriptContextFireEvent(&context, &keyEvent.d);
TEST_PROGRAM("assert(not input:isKeyActive('a'))");
TEST_PROGRAM("assert(state == C.INPUT_STATE.UP)");
mScriptContextDeinit(&context);
}
M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptInput,
cmocka_unit_test(members),
cmocka_unit_test(fireKey),
)