This commit is contained in:
helloworldlv
2025-02-17 12:06:57 +08:00
parent 36858e408a
commit 65da66e575
11 changed files with 200 additions and 149 deletions
+2 -2
View File
@@ -82,9 +82,9 @@ set(${PROJECT_NAME}_src
../../../source/conch/Bridge/JCConchBridge.cpp
../../../source/napi/helper/NapiHelper.cpp
../../../source/conch/JSWrapper/LayaWrap/JSSensor.cpp
../../../source/napi/helper/NapiValueConverter.cpp
../../../source/conch/JSWrapper/LayaWrap/JSSensor.cpp
../../../source/napi/plugin_manager.cpp
../../../source/napi/helper/NapiValueConverter.cpp
../../../source/napi/WorkerMessageQueue.cpp
../../../source/napi/render/plugin_render.cpp
../../../source/napi/render/egl_core.cpp
@@ -88,9 +88,10 @@ extern void reflectionCallback(const std::string& jsonret);
const char* methodReturnType = signature.methodReturnType;
if (!strcmp(methodReturnType, "@")) {
NSLog(@"method return type %s",methodReturnType);
id returnValue;
id __unsafe_unretained returnValue;
[invocation getReturnValue:&returnValue];
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:returnValue, @"v",nil];
id strongValue = returnValue;
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:strongValue, @"v",nil];
NSError* pError = nil;
NSData* pJsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&pError];
if (pError) {
+24 -6
View File
@@ -30,6 +30,7 @@
#include "JSWrapper/v8debug/debug-agent.h"
#elif JS_JSVM
#include "JSWrapper/v8debug/debug-agent.h"
#include "ark_runtime/jsvm.h"
#endif
//#include "btBulletDynamicsCommon.h"
@@ -311,8 +312,6 @@ namespace laya
JCPerfHUD::resetFrame();
#ifdef JS_V8
JSObjNode::s_pListJSObj = new JCSimpList();
#elif JS_JSVM
JSObjNode::s_pListJSObj = new JCSimpList();
#ifdef JS_V8_DEBUGGER
if (m_pDbgAgent)
{
@@ -324,6 +323,18 @@ namespace laya
LOGI("js debug closed");
}
#endif
#elif JS_JSVM
JSObjNode::s_pListJSObj = new JCSimpList();
//#ifdef JS_V8_DEBUGGER
auto env = ENV;
if (JCConch::s_pConch->m_nJSDebugMode != JS_DEBUG_MODE_OFF)
{
OH_JSVM_OpenInspector(env, "localhost", JCConch::s_pConch->m_nJSDebugPort);
if (JCConch::s_pConch->m_nJSDebugMode == JS_DEBUG_MODE_WAIT) {
OH_JSVM_WaitForDebugger(env, true);
}
}
//#endif
#endif
JCConch::s_pConchRender->m_pImageManager->resetJSThread();
@@ -439,6 +450,12 @@ namespace laya
delete JSObjNode::s_pListJSObj;
JSObjNode::s_pListJSObj = nullptr;
}
#ifdef JS_V8_DEBUGGER
if (m_pDbgAgent)
{
m_pDbgAgent->onJSExit();
}
#endif
#elif JS_JSVM
JSObjBaseJSVM::restarting = true;
JSObjBaseJSVM::resetBaseSet();
@@ -456,12 +473,13 @@ namespace laya
delete JSObjNode::s_pListJSObj;
JSObjNode::s_pListJSObj = nullptr;
}
#ifdef JS_V8_DEBUGGER
if (m_pDbgAgent)
//#ifdef JS_V8_DEBUGGER
auto env = ENV;
if (JCConch::s_pConch->m_nJSDebugMode != JS_DEBUG_MODE_OFF)
{
m_pDbgAgent->onJSExit();
OH_JSVM_CloseInspector(env);
}
#endif
//#endif
#elif JS_JSC
JSP_RESET_GLOBAL_FUNCTION;
#endif
@@ -84,20 +84,73 @@ public:
}
};
inline int64_t getInt64Noloss(JSVM_Value value)
{
int64_t result;
JSVM_Status status;
bool lossless;
status = OH_JSVM_GetValueBigintInt64(ENV, value, &result, &lossless);
//DEBUG_CHECK(lossless == true);
//DEBUG_CHECK(status == jsvm_status::jsvm_ok);
return result;
}
inline JSVM_Value makeInt64Noloss(int64_t value)
{
JSVM_Value result;
JSVM_Status status;
status = OH_JSVM_CreateBigintInt64(ENV, value, &result);
return result;
}
inline uint64_t getUint64Noloss(JSVM_Value value)
{
uint64_t result;
JSVM_Status status;
bool lossless;
status = OH_JSVM_GetValueBigintUint64(ENV, value, &result, &lossless);
//DEBUG_CHECK(lossless == true);
//DEBUG_CHECK(status == jsvm_status::jsvm_ok);
return result;
}
inline JSVM_Value makeUint64Noloss(uint64_t value)
{
JSVM_Value result;
JSVM_Status status;
status = OH_JSVM_CreateBigintUint64(ENV, value, &result);
return result;
}
inline bool isBigInt(JSVM_Value value)
{
JSVM_ValueType valueType;
JSVM_Status status = OH_JSVM_Typeof(ENV, value, &valueType);
//DEBUG_CHECK(status == jsvm_status::jsvm_ok);
return valueType == JSVM_ValueType::JSVM_BIGINT;
}
// 用bigint 保证精度不丢失,可以用于bullet对象指针
template <> class __TransferToCpp<int64_t> {
public:
static int64_t ToCpp(JSVM_Value p_vl) {
JSVM_Status status;
int64_t result;
JSVM_API_CALL(status, ENV, OH_JSVM_GetValueInt64(ENV, p_vl, &result));
return result;
//JSVM_Status status;
//int64_t result;
//JSVM_API_CALL(status, ENV, OH_JSVM_GetValueInt64(ENV, p_vl, &result));
//return result;
JSVM_ValueType valueType;
JSVM_Status status = OH_JSVM_Typeof(ENV, p_vl, &valueType);
//DEBUG_CHECK(status == JSVM_OK);
if (valueType == JSVM_ValueType::JSVM_NULL || valueType == JSVM_ValueType::JSVM_UNDEFINED)
{
return 0;
}
return getInt64Noloss(p_vl);
}
static bool is(JSVM_Value p_vl) {
JSVM_Status status;
bool is_number;
JSVM_API_CALL(status, ENV, OH_JSVM_IsNumber(ENV, p_vl, &is_number));
return is_number;
//JSVM_Status status;
//bool is_number;
//JSVM_API_CALL(status, ENV, OH_JSVM_IsNumber(ENV, p_vl, &is_number));
//return is_number;
return isBigInt(p_vl);
}
};
@@ -121,17 +174,19 @@ public:
template <> class __TransferToCpp<uint64_t> {
public:
static uint64_t ToCpp(JSVM_Value p_vl) {
JSVM_Status status;
int64_t result;
JSVM_API_CALL(status, ENV, OH_JSVM_GetValueInt64(ENV, p_vl, &result));
return *reinterpret_cast<uint64_t *>(&result);
//JSVM_Status status;
//int64_t result;
//JSVM_API_CALL(status, ENV, OH_JSVM_GetValueInt64(ENV, p_vl, &result));
//return *reinterpret_cast<uint64_t *>(&result);
return getUint64Noloss(p_vl);
}
static bool is(JSVM_Value p_vl) {
JSVM_Status status;
bool is_number;
JSVM_API_CALL(status, ENV, OH_JSVM_IsNumber(ENV, p_vl, &is_number));
return is_number;
//JSVM_Status status;
//bool is_number;
//JSVM_API_CALL(status, ENV, OH_JSVM_IsNumber(ENV, p_vl, &is_number));
//return is_number;
return isBigInt(p_vl);
}
};
@@ -410,10 +465,11 @@ public:
template <> class __TransferToJs<int64_t> {
public:
static JSVM_Value ToJs(int64_t p_vl) {
JSVM_Status status;
JSVM_Value result;
JSVM_API_CALL(status, ENV, OH_JSVM_CreateInt64(ENV, p_vl, &result));
return result;
//JSVM_Status status;
//JSVM_Value result;
//JSVM_API_CALL(status, ENV, OH_JSVM_CreateInt64(ENV, p_vl, &result));
//return result;
return makeInt64Noloss(p_vl);
}
static JSVM_Value ToJsDate(int64_t p_vl) {
@@ -444,10 +500,11 @@ public:
template <> class __TransferToJs<uint64_t> {
public:
static JSVM_Value ToJs(uint64_t p_vl) {
JSVM_Status status;
JSVM_Value result;
JSVM_API_CALL(status, ENV, OH_JSVM_CreateInt64(ENV, p_vl, &result));
return result;
//JSVM_Status status;
//JSVM_Value result;
//JSVM_API_CALL(status, ENV, OH_JSVM_CreateInt64(ENV, p_vl, &result));
//return result;
return makeUint64Noloss(p_vl);
}
static JSVM_Value ToJsDate(uint64_t p_vl) {
@@ -374,13 +374,13 @@ namespace laya
const char* JSConchConfig::getRuntimeVersion()
{
#ifdef __APPLE__
return "ios-conch6-release-2.13.8";
return "ios-conch6-release-2.13.9";
#elif ANDROID
return "android-conch6-release-2.13.8";
return "android-conch6-release-2.13.9";
#elif OHOS
return "ohos-conch6-release-2.13.8";
return "ohos-conch6-release-2.13.9";
#elif WIN32
return "window-conch6-release-2.13.8";
return "window-conch6-release-2.13.9";
#endif
}
const char* JSConchConfig::getAppVersion()
@@ -274,7 +274,9 @@ namespace laya
return m_strReturn.c_str();
#elif OHOS
// 暂不支持调用非静态方法
return NapiHelper::GetInstance()->callNativeMethod(isSyn, clsName, methodName, paramStr);
m_strReturn = NapiHelper::GetInstance()->callNativeMethod(isSyn, clsName, methodName, paramStr);
LOGI("JSRuntime::callMethod %s", m_strReturn.c_str());
return m_strReturn.c_str();
#endif
return "";
}
+11 -50
View File
@@ -535,82 +535,43 @@ std::string NapiHelper::callNativeMethod(bool isSyn, const char* clsPath, const
std::string NapiHelper::__callNativeMethod(bool isSyn, const char* clsPath, const char* methodName, const char* paramStr)
{
const char* module_name;
const char* method;
std::string module_name;
std::string method;
std::string methodStr = methodName;
std::string::size_type pos = methodStr.find("/");
if (pos != std::string::npos) {
std::string str1 = methodStr.substr(0, pos);
module_name = str1.c_str();
std::string str2 = methodStr.substr(pos + 1);
method = str2.c_str();
module_name = methodStr.substr(0, pos);
method = methodStr.substr(pos + 1);
} else {
method = methodName;
std::string pathStr = clsPath;
pos = pathStr.find("/");
module_name = pos != std::string::npos ? pathStr.substr(0, pos).c_str() : "entry";
module_name = pos != std::string::npos ? pathStr.substr(0, pos) : "entry";
}
napi_env env = aki::JSBind::GetScopedEnv();
napi_status status;
napi_value result;
char* module_info = __getModuleInfo(module_name);
status = napi_load_module_with_info(env, clsPath, module_info, &result);
if (status != napi_ok) {
LOGW("callNativeMethod napi_load_module_with_info fail, status=%{public}d", status);
return "";
}
napi_value func;
status = napi_get_named_property(env, result, method, &func);
if (status != napi_ok) {
LOGW("callNativeMethod napi_get_named_property fail, status=%{public}d", status);
return "";
}
// 同步方法直接调用napi_call_function
if (isSyn) {
napi_value jsArg = NapiValueConverter::ToNapiValue(env, paramStr);
napi_value return_val;
status = napi_call_function(env, result, func, 1, &jsArg, &return_val);
if (status != napi_ok) {
LOGW("callNativeMethod napi_call_function fail, status=%{public}d", status);
return "";
}
if (!NapiValueConverter::ToCppValue(env, return_val, methodResult)) {
// Handle erroe here
LOGE("NapiValueConverter::ToCppValue Fail");
}
return methodResult;
}
std::string module_info = __getModuleInfo(module_name.c_str());
std::promise<std::string> promise;
std::function<void(std::string)> cb = [&promise](std::string message)
{
promise.set_value(message);
};
AsyncCallParam *callParam = new AsyncCallParam{cb, paramStr, func};
AsyncCallParam *callParam = new AsyncCallParam{cb, paramStr, isSyn, clsPath, methodName, method, module_info};
JSFunction::getFunction("HandleMessageUtils.executeNativeMethod").invokeAsync(callParam);
methodResult = promise.get_future().get();
return methodResult;
}
char* NapiHelper::__getModuleInfo(const char* module_name)
std::string NapiHelper::__getModuleInfo(const char* module_name)
{
if (bundle_name == NULL) {
if (bundle_name.empty()) {
OH_NativeBundle_ApplicationInfo info = OH_NativeBundle_GetCurrentApplicationInfo();
bundle_name = info.bundleName;
}
char* module_info = (char*)malloc((strlen(bundle_name) + strlen(module_name) + 1) * sizeof(char*));
strcpy(module_info, "");
strcat(module_info, bundle_name);
strcat(module_info, "/");
strcat(module_info, module_name);
std::string module_info = bundle_name + "/" + module_name;
return module_info;
}
@@ -680,4 +641,4 @@ void NapiHelper::__handleShowWebview() {
}
}
std::unordered_map<std::string, JSFunction> JSFunction::FUNCTION_MAP;
std::unordered_map<std::string, JSFunction> JSFunction::FUNCTION_MAP;
+38 -52
View File
@@ -1,6 +1,7 @@
#include "../conch/JCConch.h"
#include <hilog/log.h>
#include "aki/jsbind.h"
#include <napi/native_api.h>
#include "NapiValueConverter.h"
using namespace laya;
@@ -8,7 +9,11 @@ using namespace laya;
struct AsyncCallParam {
std::function<void(std::string)> cb;// 执行异步回调后的c++回调
std::string paramStr;// 执行异步js方法的参数
napi_value callFunc;// 需要执行的js异步方法
bool isSyn;
const char* clsPath;
const char* methodName;
std::string method;
std::string module_info;
napi_ref executeFuncRef;// 安全函数调用方法的指针
};
@@ -103,7 +108,7 @@ private:
std::string __postSyncMessageToUIThread(std::string eventName, std::string data);
std::string __postCmdToMain(std::string data);
std::string __callNativeMethod(bool isSyn, const char* clsPath, const char* methodName, const char* paramStr);
char* __getModuleInfo(const char* module_name);
std::string __getModuleInfo(const char* module_name);
void __handleCloseWebview();
void __handleCreateWebview(const char *sUrl, int x, int y, int w, int h, bool bCloseWebview);
void __handleCallWebviewJS(const char *sFunctionName, const char *sJsonParam, const char *sCallbackFunction);
@@ -125,7 +130,7 @@ private:
int avalidMem;
int usedMem;
std::string methodResult;
char* bundle_name;
std::string bundle_name;
};
class JSFunction {
@@ -204,14 +209,14 @@ public:
status = napi_get_reference_value(env, funcRef, &func);
if (status != napi_ok) {
LOGW("invokeAsync napi_get_reference_value fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
napi_value workName;
status = napi_create_string_utf8(env, "Thread-safe call from async work", NAPI_AUTO_LENGTH, &workName);
if (status != napi_ok) {
LOGW("invokeAsync napi_create_string_utf8 fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
napi_threadsafe_function save_func;
@@ -219,19 +224,19 @@ public:
[](napi_env env, void *raw, void *hint) {}, callParam, CallJS, &save_func);
if (status != napi_ok) {
LOGW("invokeAsync napi_create_threadsafe_function fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
status = napi_acquire_threadsafe_function(save_func);
if (status != napi_ok) {
LOGW("invokeAsync napi_acquire_threadsafe_function fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
status = napi_call_threadsafe_function(save_func, NULL, napi_tsfn_blocking);
if (status != napi_ok) {
LOGW("invokeAsync napi_call_threadsafe_function fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
}
@@ -241,70 +246,51 @@ public:
AsyncCallParam *callParam = (AsyncCallParam*) (context);
if (callParam == nullptr) {
LOGW("CallJS AsyncCallParam callParam is null");
return;
return callParam->cb("napi_error");
}
napi_status status;
status = napi_get_reference_value(env, callParam->executeFuncRef, &js_cb);
if (status != napi_ok) {
LOGW("CallJS napi_get_reference_value fail,status=%{public}d", status);
return;
return callParam->cb("napi_error");
}
auto callback = [](napi_env env, napi_callback_info info) -> napi_value {
size_t argc = 1;
napi_value args[1] = {};
void *param_in = nullptr;
napi_get_cb_info(env, info, &argc, args, nullptr, &param_in);
napi_value return_val;
napi_get_undefined(env, &return_val);
AsyncCallParam *callbackParam = reinterpret_cast<AsyncCallParam *>(param_in);
if (callbackParam == nullptr) {
LOGW("CallJS AsyncCallParam callbackParam is null");
return return_val;
}
napi_valuetype type;
napi_typeof(env, args[0], &type);
if (type == napi_string) {
std::string resultStr;
NapiValueConverter::ToCppValue(env, args[0], resultStr);
callbackParam->cb(resultStr);
} else if (type == napi_number) {
int resultNum;
NapiValueConverter::ToCppValue(env, args[0], resultNum);
callbackParam->cb(std::to_string(resultNum));
} else if (type == napi_boolean) {
bool resultBol;
NapiValueConverter::ToCppValue(env, args[0], resultBol);
callbackParam->cb(std::to_string(resultBol));
} else {
callbackParam->cb("unknown");
}
return return_val;
};
napi_value callbackFunc = nullptr;
status = napi_create_function(env, "callbackFunc", NAPI_AUTO_LENGTH, callback, callParam, &callbackFunc);
napi_value result;
status = napi_load_module_with_info(env, callParam->clsPath, callParam->module_info.c_str(), &result);
if (status != napi_ok) {
LOGW("CallJS napi_create_function fail,status=%{public}d", status);
return;
LOGW("callNativeMethod napi_load_module_with_info fail, status=%{public}d", status);
return callParam->cb("napi_error");
}
napi_value jsArgs[3] = {callParam->callFunc, NapiValueConverter::ToNapiValue(env, callParam->paramStr), callbackFunc};
napi_value callFunc;
status = napi_get_named_property(env, result, callParam->method.c_str(), &callFunc);
if (status != napi_ok) {
LOGW("callNativeMethod napi_get_named_property fail, status=%{public}d", status);
return callParam->cb("napi_error");
}
napi_value isSyn = NapiValueConverter::ToNapiValue(env, callParam->isSyn);
napi_value cName = NapiValueConverter::ToNapiValue(env, callParam->clsPath);
napi_value mName = NapiValueConverter::ToNapiValue(env, callParam->methodName);
napi_value paramStr = NapiValueConverter::ToNapiValue(env, callParam->paramStr);
napi_value jsArgs[5] = {isSyn, cName, mName, callFunc, paramStr};
napi_value return_val;
napi_value global;
status = napi_get_global(env, &global);
if (status != napi_ok) {
LOGW("CallJS napi_get_global fail,status=%{public}d", status);
return callParam->cb("napi_error");
}
status = napi_call_function(env, global, js_cb, 3, jsArgs, &return_val);
status = napi_call_function(env, global, js_cb, 5, jsArgs, &return_val);
if (status != napi_ok) {
LOGW("CallJS napi_call_function fail,status=%{public}d", status);
return callParam->cb("napi_error");
}
std::string resultStr;
NapiValueConverter::ToCppValue(env, return_val, resultStr);
callParam->cb(resultStr);
}
};
+2 -2
View File
@@ -6,7 +6,7 @@
#include "modules/VideoPlayerNapi.h"
#include "plugin_manager.h"
#include "napi/helper/JSRegisterUtils.h"
#include "helper/JsRegisterUtils.h"
#include <aki/jsbind.h>
#include "util/Log.h"
@@ -77,7 +77,7 @@ napi_value NapiManager::GetContext(long contextEnum)
LOGI("NapiManager::GetContext NATIVE_RENDER_API");
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("nativeEngineStart", NapiManager::napiNativeEngineStart),
DECLARE_NAPI_FUNCTION("registerFunction", registerFunction),
DECLARE_NAPI_FUNCTION("registerFunction", registerFunction)
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}
@@ -30,3 +30,4 @@ export const ConchNAPI_setLocalizable: (p_bIsLocalPackage: boolean) => void;
export const ConchNAPI_OnAppStart: () => void;
export const ConchNAPI_inputChange:(keycode:number) => void;
export const ConchNAPI_gameMsgHandle:(key:string, data:string) => void;
export const ConchNAPI_RunJS:(jsstr:string) => void;
@@ -41,12 +41,37 @@ export class HandleMessageUtils {
}
/**
* aki执行本地自定义异步方法
* @param nativeFunc
* @param funcData
* @param funcCb
* PlatformClass反射调用本地自定义方法
* @param isSyn
* @param cName
* @param mName
* @param nativeFunc
* @param paramStr
*/
static executeNativeMethod(nativeFunc: Function, funcData: string, funcCb: Function): void {
nativeFunc && nativeFunc(funcData, funcCb);
static executeNativeMethod(isSyn: boolean, cName: string, mName: string, nativeFunc: Function, paramStr: string): string {
let jParam = JSON.parse(paramStr || "[]");
let result = null;
if (isSyn) {
result = nativeFunc && nativeFunc.apply(this, jParam);
} else {
let paramCb = (call_re: string) => {
let rsJson = {
objId: -1,
cName: cName,
mName: mName,
v: call_re
}
laya.ConchNAPI_RunJS("conch.platCallBack(" + JSON.stringify(rsJson) + ")");
};
jParam[jParam.length] = paramCb;
result = nativeFunc && nativeFunc.apply(this, jParam);
}
let rsJson = {
v: result
}
return JSON.stringify(rsJson);
}
}