mirror of https://github.com/mgba-emu/mgba.git
Scripting: Clear down keys when the window is deactivated
This commit is contained in:
parent
f27ce8d82e
commit
e95bd06321
|
@ -249,6 +249,7 @@ mSCRIPT_DECLARE_STRUCT(mScriptGamepad);
|
|||
void mScriptContextAttachInput(struct mScriptContext* context);
|
||||
|
||||
void mScriptContextFireEvent(struct mScriptContext*, struct mScriptEvent*);
|
||||
void mScriptContextClearKeys(struct mScriptContext*);
|
||||
|
||||
int mScriptContextGamepadAttach(struct mScriptContext*, struct mScriptGamepad*);
|
||||
bool mScriptContextGamepadDetach(struct mScriptContext*, int pad);
|
||||
|
|
|
@ -155,6 +155,10 @@ void ScriptingController::event(QObject* obj, QEvent* event) {
|
|||
}
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::FocusOut:
|
||||
case QEvent::WindowDeactivate:
|
||||
mScriptContextClearKeys(&m_scriptContext);
|
||||
return;
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease: {
|
||||
struct mScriptKeyEvent ev{mSCRIPT_EV_TYPE_KEY};
|
||||
|
|
|
@ -427,6 +427,44 @@ void mScriptContextFireEvent(struct mScriptContext* context, struct mScriptEvent
|
|||
mScriptListDeinit(&args);
|
||||
}
|
||||
|
||||
void mScriptContextClearKeys(struct mScriptContext* context) {
|
||||
struct mScriptValue* input = mScriptContextGetGlobal(context, "input");
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
struct mScriptInputContext* inputContext = input->value.opaque;
|
||||
size_t keyCount = TableSize(&inputContext->activeKeys);
|
||||
uint32_t* keys = calloc(keyCount, sizeof(uint32_t));
|
||||
struct TableIterator iter;
|
||||
size_t i = 0;
|
||||
if (!TableIteratorStart(&inputContext->activeKeys, &iter)) {
|
||||
free(keys);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
keys[i] = TableIteratorGetKey(&inputContext->activeKeys, &iter);
|
||||
++i;
|
||||
} while (TableIteratorNext(&inputContext->activeKeys, &iter));
|
||||
|
||||
struct mScriptKeyEvent event = {
|
||||
.d = {
|
||||
.type = mSCRIPT_EV_TYPE_KEY
|
||||
},
|
||||
.state = mSCRIPT_INPUT_STATE_UP,
|
||||
.modifiers = 0
|
||||
};
|
||||
for (i = 0; i < keyCount; ++i) {
|
||||
event.key = keys[i];
|
||||
intptr_t value = (intptr_t) TableLookup(&inputContext->activeKeys, event.key);
|
||||
if (value > 1) {
|
||||
TableInsert(&inputContext->activeKeys, event.key, (void*) 1);
|
||||
}
|
||||
mScriptContextFireEvent(context, &event.d);
|
||||
}
|
||||
|
||||
free(keys);
|
||||
}
|
||||
|
||||
int mScriptContextGamepadAttach(struct mScriptContext* context, struct mScriptGamepad* pad) {
|
||||
struct mScriptValue* input = mScriptContextGetGlobal(context, "input");
|
||||
if (!input) {
|
||||
|
|
|
@ -131,6 +131,50 @@ M_TEST_DEFINE(activeKeys) {
|
|||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(clearKeys) {
|
||||
SETUP_LUA;
|
||||
|
||||
TEST_PROGRAM("assert(not input:isKeyActive('a'))");
|
||||
TEST_PROGRAM("assert(not input:isKeyActive('b'))");
|
||||
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);
|
||||
// This changes it to STATE_HELD, but increments the down counter
|
||||
mScriptContextFireEvent(&context, &keyEvent.d);
|
||||
keyEvent.state = mSCRIPT_INPUT_STATE_DOWN;
|
||||
keyEvent.key = 'b';
|
||||
mScriptContextFireEvent(&context, &keyEvent.d);
|
||||
|
||||
TEST_PROGRAM("assert(input:isKeyActive('a'))");
|
||||
TEST_PROGRAM("assert(input:isKeyActive('b'))");
|
||||
TEST_PROGRAM("assert(#input:activeKeys() == 2)");
|
||||
|
||||
TEST_PROGRAM(
|
||||
"up = {}\n"
|
||||
"function cb(ev)\n"
|
||||
" assert(ev.type == C.EV_TYPE.KEY)\n"
|
||||
" assert(ev.state == C.INPUT_STATE.UP)\n"
|
||||
" table.insert(up, ev.key)\n"
|
||||
"end\n"
|
||||
"id = callbacks:add('key', cb)\n"
|
||||
);
|
||||
|
||||
mScriptContextClearKeys(&context);
|
||||
|
||||
TEST_PROGRAM("assert(not input:isKeyActive('a'))");
|
||||
TEST_PROGRAM("assert(not input:isKeyActive('b'))");
|
||||
TEST_PROGRAM("assert(#input:activeKeys() == 0)");
|
||||
TEST_PROGRAM("assert(#up == 2)");
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
|
||||
M_TEST_DEFINE(gamepadExport) {
|
||||
SETUP_LUA;
|
||||
|
||||
|
@ -176,5 +220,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptInput,
|
|||
cmocka_unit_test(seq),
|
||||
cmocka_unit_test(fireKey),
|
||||
cmocka_unit_test(activeKeys),
|
||||
cmocka_unit_test(clearKeys),
|
||||
cmocka_unit_test(gamepadExport),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue