Scripting: Add input:activeKeys to get currently active keyboard keys

This commit is contained in:
Vicki Pfau 2023-01-31 21:34:19 -08:00
parent 4afacfa067
commit f27ce8d82e
2 changed files with 41 additions and 1 deletions

View File

@ -36,17 +36,21 @@ struct mScriptInputContext {
static void _mScriptInputDeinit(struct mScriptInputContext*); static void _mScriptInputDeinit(struct mScriptInputContext*);
static bool _mScriptInputIsKeyActive(const struct mScriptInputContext*, struct mScriptValue*); static bool _mScriptInputIsKeyActive(const struct mScriptInputContext*, struct mScriptValue*);
static struct mScriptValue* _mScriptInputActiveKeys(const struct mScriptInputContext*);
mSCRIPT_DECLARE_STRUCT(mScriptInputContext); mSCRIPT_DECLARE_STRUCT(mScriptInputContext);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptInputContext, _deinit, _mScriptInputDeinit, 0); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptInputContext, _deinit, _mScriptInputDeinit, 0);
mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActive, _mScriptInputIsKeyActive, 1, WRAPPER, key); mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActive, _mScriptInputIsKeyActive, 1, WRAPPER, key);
mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, WLIST, activeKeys, _mScriptInputActiveKeys, 0);
mSCRIPT_DEFINE_STRUCT(mScriptInputContext) mSCRIPT_DEFINE_STRUCT(mScriptInputContext)
mSCRIPT_DEFINE_STRUCT_DEINIT(mScriptInputContext) mSCRIPT_DEFINE_STRUCT_DEINIT(mScriptInputContext)
mSCRIPT_DEFINE_DOCSTRING("Sequence number of the next event to be emitted") mSCRIPT_DEFINE_DOCSTRING("Sequence number of the next event to be emitted")
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptInputContext, U64, seq) mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptInputContext, U64, seq)
mSCRIPT_DEFINE_DOCSTRING("Check if a given keyboard key is currently held. The input can be either the printable character for a key, or the numerical Unicode codepoint") mSCRIPT_DEFINE_DOCSTRING("Check if a given keyboard key is currently held. The input can be either the printable character for a key, the numerical Unicode codepoint, or a special value from C.KEY")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, isKeyActive) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, isKeyActive)
mSCRIPT_DEFINE_DOCSTRING("Get a list of the currently active keys. The values are Unicode codepoints or special key values from C.KEY, not strings, so make sure to convert as needed")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, activeKeys)
mSCRIPT_DEFINE_DOCSTRING("The currently active gamepad, if any") mSCRIPT_DEFINE_DOCSTRING("The currently active gamepad, if any")
mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptInputContext, PCS(mScriptGamepad), activeGamepad) mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptInputContext, PCS(mScriptGamepad), activeGamepad)
mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_END;
@ -346,6 +350,19 @@ bool _mScriptInputIsKeyActive(const struct mScriptInputContext* context, struct
return down != NULL; return down != NULL;
} }
static struct mScriptValue* _mScriptInputActiveKeys(const struct mScriptInputContext* context) {
struct mScriptValue* list = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST);
struct TableIterator iter;
if (!TableIteratorStart(&context->activeKeys, &iter)) {
return list;
}
do {
uint32_t key = TableIteratorGetKey(&context->activeKeys, &iter);
*mScriptListAppend(list->value.list) = mSCRIPT_MAKE_U32(key);
} while (TableIteratorNext(&context->activeKeys, &iter));
return list;
}
static bool _updateKeys(struct mScriptContext* context, struct mScriptKeyEvent* event) { static bool _updateKeys(struct mScriptContext* context, struct mScriptKeyEvent* event) {
int offset = 0; int offset = 0;
switch (event->state) { switch (event->state) {

View File

@ -109,6 +109,28 @@ M_TEST_DEFINE(fireKey) {
mScriptContextDeinit(&context); mScriptContextDeinit(&context);
} }
M_TEST_DEFINE(activeKeys) {
SETUP_LUA;
TEST_PROGRAM("assert(#input:activeKeys() == 0)");
struct mScriptKeyEvent keyEvent = {
.d = { .type = mSCRIPT_EV_TYPE_KEY },
.state = mSCRIPT_INPUT_STATE_DOWN,
.key = 'a'
};
mScriptContextFireEvent(&context, &keyEvent.d);
TEST_PROGRAM("assert(#input:activeKeys() == 1)");
TEST_PROGRAM("assert(input:activeKeys()[1] == string.byte('a'))");
keyEvent.state = mSCRIPT_INPUT_STATE_UP;
mScriptContextFireEvent(&context, &keyEvent.d);
TEST_PROGRAM("assert(#input:activeKeys() == 0)");
mScriptContextDeinit(&context);
}
M_TEST_DEFINE(gamepadExport) { M_TEST_DEFINE(gamepadExport) {
SETUP_LUA; SETUP_LUA;
@ -153,5 +175,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptInput,
cmocka_unit_test(members), cmocka_unit_test(members),
cmocka_unit_test(seq), cmocka_unit_test(seq),
cmocka_unit_test(fireKey), cmocka_unit_test(fireKey),
cmocka_unit_test(activeKeys),
cmocka_unit_test(gamepadExport), cmocka_unit_test(gamepadExport),
) )