From 36f030fba492c187e416fd4669489c821d7c3529 Mon Sep 17 00:00:00 2001 From: cebgcontract <99630598+cebgcontract@users.noreply.github.com> Date: Fri, 16 Sep 2022 20:26:04 +0800 Subject: [PATCH] =?UTF-8?q?js=E5=9B=9E=E8=B0=83=E4=BD=BF=E7=94=A8=E4=B8=BB?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Classes/JcWallet.cpp | 48 ++++++++++++++++++++++++++++++++++++++------ Classes/JcWallet.h | 4 ++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Classes/JcWallet.cpp b/Classes/JcWallet.cpp index e30fc01..2e87e4b 100644 --- a/Classes/JcWallet.cpp +++ b/Classes/JcWallet.cpp @@ -26,6 +26,7 @@ NS_CC_BEGIN cocos2d::Application *g_app = nullptr; JcWallet *JcWallet::_instance = nullptr; + uv_loop_t *loop = nullptr; bool _isStarted = false; uv_async_t gasync = {0}; @@ -50,7 +51,7 @@ NS_CC_BEGIN void init_libuv_async_handle(uv_async_t *async) { memset(async, 0, sizeof(uv_async_t)); // uv_loop_t *loop = uv_default_loop(); - uv_loop_t* loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); + loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); uv_loop_init(loop); uv_async_init(loop, async, cocos2d::flush_tasks_in_server_loop_cb); async->data = new AsyncTaskData(); @@ -68,7 +69,12 @@ NS_CC_BEGIN //notify server thread to invoke `flush_tasks_in_server_loop_cb()` return uv_async_send(asyn); } - +#define RUN_IN_GAMETHREAD(task) \ + do { \ + JcWallet::getInstance()->performFunctionInCocosThread([=]() { \ + task; \ + });\ + } while(0) #define RUN_IN_SERVERTHREAD(task) do { \ schedule_task_into_server_thread_task_queue(&gasync, [=](){ \ task; \ @@ -97,6 +103,8 @@ NS_CC_BEGIN JcWallet::JcWallet() { JcWallet::_instance = this; + _functionsToPerform.reserve(30); + std::unique_lock lock(_performMutex); } void JcWallet::initEnv() { @@ -110,6 +118,7 @@ NS_CC_BEGIN g_app->start(); _isStarted = true; WalletEvent::Emit("wallet_init_event", "{}"); +// RUN_IN_GAMETHREAD(JcWallet::getInstance()->jsToUnity("wallet_init_event", "{}")); cocos2d::init_libuv_async_handle(&gasync); } } @@ -126,7 +135,7 @@ NS_CC_BEGIN JcWallet::~JcWallet() { EventDispatcher::destroy(); se::ScriptEngine::destroyInstance(); - uv_loop_close(uv_default_loop()); + uv_loop_close(loop); JcWallet::_instance = nullptr; } @@ -142,14 +151,40 @@ NS_CC_BEGIN result = ""; } cocos2d::log("method: %s ::result: %s", data->methodName.c_str(), result.c_str()); - WalletEvent::Emit(data->funId.c_str(), result.c_str()); + RUN_IN_GAMETHREAD(JcWallet::getInstance()->jsToUnity(data->funId, result)); +// WalletEvent::Emit(data->funId.c_str(), result.c_str()); } return const_cast(result.c_str()); } + void JcWallet::performFunctionInCocosThread( const std::function &function) { + _performMutex.lock(); + _functionsToPerform.push_back(function); + _performMutex.unlock(); + } + + void JcWallet::tickRun() { + if( !_functionsToPerform.empty() ) { + _performMutex.lock(); + // fixed #4123: Save the callback functions, they must be invoked after '_performMutex.unlock()', otherwise if new functions are added in callback, it will cause thread deadlock. + auto temp = _functionsToPerform; + _functionsToPerform.clear(); + _performMutex.unlock(); + for( const auto &function : temp ) { + function(); + } + + } + } + + void JcWallet::jsToUnity(std::string funId, std::string msg) { + WalletEvent::Emit(funId.c_str(), msg.c_str()); + } + extern "C" { void initEnv() { if (!_isStarted) { + new JcWallet(); std::shared_ptr wallet(JcWallet::getInstance()); std::thread([=]() { JcWallet::initJSThread(wallet); @@ -161,6 +196,7 @@ NS_CC_BEGIN schedule_task_into_server_thread_task_queue(&gasync, [=](){ JcWallet::getInstance()->tick(dt); }); + JcWallet::getInstance()->tickRun(); } } @@ -179,7 +215,6 @@ NS_CC_BEGIN int result = schedule_task_into_server_thread_task_queue(&gasync, [=](){ JcWallet::getInstance()->runJsMethod(params); }); -// RUN_IN_SERVERTHREAD(JcWallet::getInstance()->runJsMethod(params)); return result == 0 ? 1 : 0; } } @@ -215,7 +250,8 @@ bool jsb_wallet_callback(se::State& s) { std::string msg; ok = seval_to_std_string(args[1], &msg); SE_PRECONDITION2(ok, false, "Error processing arguments"); - WalletEvent::Emit(funId.c_str(), msg.c_str()); +// WalletEvent::Emit(funId.c_str(), msg.c_str()); + RUN_IN_GAMETHREAD(JcWallet::getInstance()->jsToUnity(funId, msg)); return true; } return false; diff --git a/Classes/JcWallet.h b/Classes/JcWallet.h index 7aeccff..4fe7717 100644 --- a/Classes/JcWallet.h +++ b/Classes/JcWallet.h @@ -36,6 +36,10 @@ NS_CC_BEGIN void performFunctionInCocosThread( const std::function &function); + void tickRun(); + + void jsToUnity(std::string funId, std::string msg); + private: static JcWallet *_instance; std::vector> _functionsToPerform;