1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-02 00:10:22 +02:00

fix using JNI from server in single process build

This commit is contained in:
Andrey Filipenkov 2023-02-26 12:19:24 +03:00
parent c4e7e91850
commit 313d479d42
6 changed files with 38 additions and 7 deletions

View File

@ -53,6 +53,10 @@
#include "../../lib/CondSh.h" #include "../../lib/CondSh.h"
#include "../../lib/mapping/CCampaignHandler.h" #include "../../lib/mapping/CCampaignHandler.h"
#if defined(SINGLE_PROCESS_APP) && defined(VCMI_ANDROID)
#include "../../server/CVCMIServer.h"
#include <SDL.h>
#endif
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -459,7 +463,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
if(host && !settings["session"]["donotstartserver"].Bool()) if(host && !settings["session"]["donotstartserver"].Bool())
{ {
textTitle->setText("Connecting..."); textTitle->setText("Connecting...");
boost::thread(&CSimpleJoinScreen::connectThread, this, "", 0); startConnectThread();
} }
else else
{ {
@ -484,7 +488,7 @@ void CSimpleJoinScreen::connectToServer()
buttonOk->block(true); buttonOk->block(true);
GH.stopTextInput(); GH.stopTextInput();
boost::thread(&CSimpleJoinScreen::connectThread, this, inputAddress->getText(), boost::lexical_cast<ui16>(inputPort->getText())); startConnectThread(inputAddress->getText(), boost::lexical_cast<ui16>(inputPort->getText()));
} }
void CSimpleJoinScreen::leaveScreen() void CSimpleJoinScreen::leaveScreen()
@ -505,7 +509,18 @@ void CSimpleJoinScreen::onChange(const std::string & newText)
buttonOk->block(inputAddress->getText().empty() || inputPort->getText().empty()); buttonOk->block(inputAddress->getText().empty() || inputPort->getText().empty());
} }
void CSimpleJoinScreen::connectThread(const std::string addr, const ui16 port) void CSimpleJoinScreen::startConnectThread(const std::string & addr, ui16 port)
{
#if defined(SINGLE_PROCESS_APP) && defined(VCMI_ANDROID)
// in single process build server must use same JNIEnv as client
// as server runs in a separate thread, it must not attempt to search for Java classes (and they're already cached anyway)
// https://github.com/libsdl-org/SDL/blob/main/docs/README-android.md#threads-and-the-java-vm
CVCMIServer::reuseClientJNIEnv(SDL_AndroidGetJNIEnv());
#endif
boost::thread(&CSimpleJoinScreen::connectThread, this, addr, port);
}
void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port)
{ {
setThreadName("CSimpleJoinScreen::connectThread"); setThreadName("CSimpleJoinScreen::connectThread");
if(!addr.length()) if(!addr.length())

View File

@ -167,7 +167,8 @@ class CSimpleJoinScreen : public WindowBase
void connectToServer(); void connectToServer();
void leaveScreen(); void leaveScreen();
void onChange(const std::string & newText); void onChange(const std::string & newText);
void connectThread(const std::string addr = "", const ui16 inputPort = 0); void startConnectThread(const std::string & addr = {}, ui16 port = 0);
void connectThread(const std::string & addr, ui16 port);
public: public:
CSimpleJoinScreen(bool host = true); CSimpleJoinScreen(bool host = true);

View File

@ -18,6 +18,8 @@ static JavaVM * vmCache = nullptr;
static jobject vcmiClassLoader; static jobject vcmiClassLoader;
static jmethodID vcmiFindClassMethod; static jmethodID vcmiFindClassMethod;
bool CAndroidVMHelper::alwaysUseLoadedClass = false;
void CAndroidVMHelper::cacheVM(JNIEnv * env) void CAndroidVMHelper::cacheVM(JNIEnv * env)
{ {
env->GetJavaVM(&vmCache); env->GetJavaVM(&vmCache);
@ -91,7 +93,7 @@ void CAndroidVMHelper::callCustomMethod(const std::string & cls, const std::stri
jclass CAndroidVMHelper::findClass(const std::string & name, bool classloaded) jclass CAndroidVMHelper::findClass(const std::string & name, bool classloaded)
{ {
if(classloaded) if(alwaysUseLoadedClass || classloaded)
{ {
return findClassloadedClass(name); return findClassloadedClass(name);
} }

View File

@ -46,6 +46,8 @@ public:
static void initClassloader(void * baseEnv); static void initClassloader(void * baseEnv);
static bool alwaysUseLoadedClass;
static constexpr const char * NATIVE_METHODS_DEFAULT_CLASS = "eu/vcmi/vcmi/NativeMethods"; static constexpr const char * NATIVE_METHODS_DEFAULT_CLASS = "eu/vcmi/vcmi/NativeMethods";
}; };

View File

@ -1191,4 +1191,12 @@ void CVCMIServer::create(boost::condition_variable * cond, const std::vector<std
argv.push_back(a.c_str()); argv.push_back(a.c_str());
main(argv.size(), reinterpret_cast<const char **>(&*argv.begin())); main(argv.size(), reinterpret_cast<const char **>(&*argv.begin()));
} }
#endif
#ifdef VCMI_ANDROID
void CVCMIServer::reuseClientJNIEnv(void * jniEnv)
{
CAndroidVMHelper::initClassloader(jniEnv);
CAndroidVMHelper::alwaysUseLoadedClass = true;
}
#endif // VCMI_ANDROID
#endif // VCMI_ANDROID_DUAL_PROCESS

View File

@ -121,5 +121,8 @@ public:
static void create(); static void create();
#elif defined(SINGLE_PROCESS_APP) #elif defined(SINGLE_PROCESS_APP)
static void create(boost::condition_variable * cond, const std::vector<std::string> & args); static void create(boost::condition_variable * cond, const std::vector<std::string> & args);
#endif # ifdef VCMI_ANDROID
static void reuseClientJNIEnv(void * jniEnv);
# endif // VCMI_ANDROID
#endif // VCMI_ANDROID_DUAL_PROCESS
}; };