sync thread access to text input buffer

This commit is contained in:
Struma 2021-03-08 06:20:43 -05:00 committed by Roza
parent 10f3d2655d
commit 69a89cf87f
3 changed files with 635 additions and 609 deletions

View file

@ -20,11 +20,13 @@
*/ */
#include "binding-util.h" #include "binding-util.h"
#include "exception.h" #include "util/exception.h"
#include "input.h" #include "input/input.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "src/util/util.h" #include "src/util/util.h"
#include "eventthread.h"
#include <SDL_joystick.h> #include <SDL_joystick.h>
#include <string> #include <string>
@ -323,10 +325,10 @@ RB_METHOD(inputSetMode) {
RB_METHOD(inputGets) { RB_METHOD(inputGets) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
shState->eThread().lockText(true);
VALUE ret = rb_utf8_str_new_cstr(shState->input().getText()); VALUE ret = rb_utf8_str_new_cstr(shState->input().getText());
shState->input().clearText(); shState->input().clearText();
shState->eThread().lockText(false);
return ret; return ret;
} }

View file

@ -1,23 +1,23 @@
/* /*
** eventthread.cpp ** eventthread.cpp
** **
** This file is part of mkxp. ** This file is part of mkxp.
** **
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com> ** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** **
** mkxp is free software: you can redistribute it and/or modify ** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or ** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** mkxp is distributed in the hope that it will be useful, ** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>. ** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "eventthread.h" #include "eventthread.h"
@ -52,8 +52,8 @@ typedef void (ALC_APIENTRY *LPALCDEVICEPAUSESOFT) (ALCdevice *device);
typedef void (ALC_APIENTRY *LPALCDEVICERESUMESOFT) (ALCdevice *device); typedef void (ALC_APIENTRY *LPALCDEVICERESUMESOFT) (ALCdevice *device);
#define AL_DEVICE_PAUSE_FUN \ #define AL_DEVICE_PAUSE_FUN \
AL_FUN(DevicePause, LPALCDEVICEPAUSESOFT) \ AL_FUN(DevicePause, LPALCDEVICEPAUSESOFT) \
AL_FUN(DeviceResume, LPALCDEVICERESUMESOFT) AL_FUN(DeviceResume, LPALCDEVICERESUMESOFT)
struct ALCFunctions struct ALCFunctions
{ {
@ -116,11 +116,18 @@ bool EventThread::allocUserEvents()
} }
EventThread::EventThread() EventThread::EventThread()
: js(0), : js(0),
fullscreen(false), fullscreen(false),
showCursor(true), showCursor(true),
joystickConnected(false) joystickConnected(false)
{} {
textInputLock = SDL_CreateMutex();
}
EventThread::~EventThread()
{
SDL_DestroyMutex(textInputLock);
}
void EventThread::process(RGSSThreadData &rtData) void EventThread::process(RGSSThreadData &rtData)
{ {
@ -266,8 +273,11 @@ void EventThread::process(RGSSThreadData &rtData)
break; break;
case SDL_TEXTINPUT : case SDL_TEXTINPUT :
if (textInputBuffer.size() < 512) lockText(true);
if (textInputBuffer.size() < 512) {
textInputBuffer += event.text.text; textInputBuffer += event.text.text;
}
lockText(false);
break; break;
case SDL_QUIT : case SDL_QUIT :
@ -459,12 +469,16 @@ void EventThread::process(RGSSThreadData &rtData)
if (event.user.code) if (event.user.code)
{ {
SDL_StartTextInput(); SDL_StartTextInput();
lockText(true);
textInputBuffer.clear(); textInputBuffer.clear();
lockText(false);
} }
else else
{ {
SDL_StopTextInput(); SDL_StopTextInput();
lockText(true);
textInputBuffer.clear(); textInputBuffer.clear();
lockText(false);
} }
break; break;
@ -584,13 +598,13 @@ int EventThread::eventFilter(void *data, SDL_Event *event)
Debug() << "SDL_APP_LOWMEMORY"; Debug() << "SDL_APP_LOWMEMORY";
return 0; return 0;
// case SDL_RENDER_TARGETS_RESET : // case SDL_RENDER_TARGETS_RESET :
// Debug() << "****** SDL_RENDER_TARGETS_RESET"; // Debug() << "****** SDL_RENDER_TARGETS_RESET";
// return 0; // return 0;
// case SDL_RENDER_DEVICE_RESET : // case SDL_RENDER_DEVICE_RESET :
// Debug() << "****** SDL_RENDER_DEVICE_RESET"; // Debug() << "****** SDL_RENDER_DEVICE_RESET";
// return 0; // return 0;
} }
return 1; return 1;
@ -766,6 +780,11 @@ void EventThread::notifyGameScreenChange(const SDL_Rect &screen)
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
void EventThread::lockText(bool lock)
{
lock ? SDL_LockMutex(textInputLock) : SDL_UnlockMutex(textInputLock);
}
void SyncPoint::haltThreads() void SyncPoint::haltThreads()
{ {
if (mainSync.locked) if (mainSync.locked)

View file

@ -77,10 +77,13 @@ public:
static TouchState touchState; static TouchState touchState;
std::string textInputBuffer; std::string textInputBuffer;
void lockText(bool lock);
static bool allocUserEvents(); static bool allocUserEvents();
EventThread(); EventThread();
~EventThread();
void process(RGSSThreadData &rtData); void process(RGSSThreadData &rtData);
void cleanup(); void cleanup();
@ -129,6 +132,8 @@ private:
AtomicFlag msgBoxDone; AtomicFlag msgBoxDone;
SDL_mutex *textInputLock;
struct struct
{ {
AtomicFlag sendUpdates; AtomicFlag sendUpdates;