Make android callback thread safe
This commit is contained in:
parent
febad27342
commit
a96071f9d3
@ -9,6 +9,7 @@
|
|||||||
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
|
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "CContextEGL.h"
|
#include "CContextEGL.h"
|
||||||
@ -43,7 +44,7 @@ ANDROID_SAVE_CHARS_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
|||||||
|
|
||||||
// Call when android keyboard is opened or close, and save its height for
|
// Call when android keyboard is opened or close, and save its height for
|
||||||
// moving screen
|
// moving screen
|
||||||
int g_keyboard_height = 0;
|
std::atomic<int> g_keyboard_height(0);
|
||||||
|
|
||||||
#define MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_saveKeyboardHeight(JNIEnv* env, jobject this_obj, jint height)
|
#define MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_saveKeyboardHeight(JNIEnv* env, jobject this_obj, jint height)
|
||||||
#define ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME) MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME)
|
#define ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME) MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME)
|
||||||
@ -51,7 +52,7 @@ int g_keyboard_height = 0;
|
|||||||
extern "C"
|
extern "C"
|
||||||
ANDROID_SAVE_KBD_HEIGHT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
ANDROID_SAVE_KBD_HEIGHT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||||
{
|
{
|
||||||
g_keyboard_height = (int)height;
|
g_keyboard_height.store((int)height);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -227,8 +228,9 @@ void CIrrDeviceAndroid::printConfig()
|
|||||||
|
|
||||||
u32 CIrrDeviceAndroid::getOnScreenKeyboardHeight() const
|
u32 CIrrDeviceAndroid::getOnScreenKeyboardHeight() const
|
||||||
{
|
{
|
||||||
if (g_keyboard_height > 0)
|
int height = g_keyboard_height.load();
|
||||||
return g_keyboard_height;
|
if (height > 0)
|
||||||
|
return height;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,9 +685,11 @@ namespace GUIEngine
|
|||||||
#include "states_screens/race_gui_base.hpp"
|
#include "states_screens/race_gui_base.hpp"
|
||||||
#include "utils/debug.hpp"
|
#include "utils/debug.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <irrlicht.h>
|
#include <irrlicht.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
using namespace irr::gui;
|
using namespace irr::gui;
|
||||||
using namespace irr::video;
|
using namespace irr::video;
|
||||||
@ -716,6 +718,10 @@ namespace GUIEngine
|
|||||||
int large_font_height;
|
int large_font_height;
|
||||||
int small_font_height;
|
int small_font_height;
|
||||||
int title_font_height;
|
int title_font_height;
|
||||||
|
#ifdef ANDROID
|
||||||
|
std::mutex m_gui_functions_mutex;
|
||||||
|
std::vector<std::function<void()> > m_gui_functions;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
using namespace Private;
|
using namespace Private;
|
||||||
|
|
||||||
@ -1144,6 +1150,15 @@ namespace GUIEngine
|
|||||||
assert(g_skin->getReferenceCount() == 1);
|
assert(g_skin->getReferenceCount() == 1);
|
||||||
} // reloadSkin
|
} // reloadSkin
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
void addGUIFunctionBeforeRendering(std::function<void()> func)
|
||||||
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
std::lock_guard<std::mutex> lock(m_gui_functions_mutex);
|
||||||
|
m_gui_functions.push_back(func);
|
||||||
|
#endif
|
||||||
|
} // addGUIFunctionBeforeRendering
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
/** \brief called on every frame to trigger the rendering of the GUI.
|
/** \brief called on every frame to trigger the rendering of the GUI.
|
||||||
* \param elapsed_time Time since last rendering calls (in seconds).
|
* \param elapsed_time Time since last rendering calls (in seconds).
|
||||||
@ -1158,6 +1173,21 @@ namespace GUIEngine
|
|||||||
// Not yet initialized, or already cleaned up
|
// Not yet initialized, or already cleaned up
|
||||||
if (g_skin == NULL) return;
|
if (g_skin == NULL) return;
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
// Run all GUI functions first (if any)
|
||||||
|
std::unique_lock<std::mutex> ul(m_gui_functions_mutex);
|
||||||
|
if (!m_gui_functions.empty())
|
||||||
|
{
|
||||||
|
std::vector<std::function<void()> > functions;
|
||||||
|
std::swap(functions, m_gui_functions);
|
||||||
|
ul.unlock();
|
||||||
|
for (auto& f : functions)
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ul.unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---- menu drawing
|
// ---- menu drawing
|
||||||
|
|
||||||
// draw background image and sections
|
// draw background image and sections
|
||||||
|
@ -34,6 +34,7 @@ namespace irr
|
|||||||
namespace video { class IVideoDriver; class ITexture; }
|
namespace video { class IVideoDriver; class ITexture; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
@ -248,6 +249,10 @@ namespace GUIEngine
|
|||||||
*/
|
*/
|
||||||
void reloadSkin();
|
void reloadSkin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Add gui-related function before rendering GUI (from other thread)
|
||||||
|
*/
|
||||||
|
void addGUIFunctionBeforeRendering(std::function<void()> func);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -246,8 +246,7 @@ EventPropagation TextBoxWidget::leftPressed (const int playerID)
|
|||||||
extern "C"
|
extern "C"
|
||||||
ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||||
{
|
{
|
||||||
TextBoxWidget* tb = dynamic_cast<TextBoxWidget*>(getFocusForPlayer(0));
|
if (text == NULL)
|
||||||
if (!tb || (int)widget_id != tb->getID() || text == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char* utf8_text = env->GetStringUTFChars(text, NULL);
|
const char* utf8_text = env->GetStringUTFChars(text, NULL);
|
||||||
@ -262,8 +261,17 @@ ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
|||||||
utf32line.push_back(0);
|
utf32line.push_back(0);
|
||||||
|
|
||||||
core::stringw to_editbox(&utf32line[0]);
|
core::stringw to_editbox(&utf32line[0]);
|
||||||
|
env->ReleaseStringUTFChars(text, utf8_text);
|
||||||
|
|
||||||
|
GUIEngine::addGUIFunctionBeforeRendering([widget_id, to_editbox, start,
|
||||||
|
end, composing_start, composing_end]()
|
||||||
|
{
|
||||||
|
TextBoxWidget* tb =
|
||||||
|
dynamic_cast<TextBoxWidget*>(getFocusForPlayer(0));
|
||||||
|
if (!tb || (int)widget_id != tb->getID())
|
||||||
|
return;
|
||||||
tb->getIrrlichtElement<MyCGUIEditBox>()->fromAndroidEditText(
|
tb->getIrrlichtElement<MyCGUIEditBox>()->fromAndroidEditText(
|
||||||
to_editbox, start, end, composing_start, composing_end);
|
to_editbox, start, end, composing_start, composing_end);
|
||||||
env->ReleaseStringUTFChars(text, utf8_text);
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user