#include "NativeManager.h" #include #include #include #include #include #include "arkui/native_node.h" #include "arkui/native_node_napi.h" #include "arkui/native_interface.h" #include "common.h" #include #include #define COLUMN_MARGIN 10 #define XC_WIDTH 800 #define XC_HEIGHT 600 #define ARG_CNT 2 #ifndef NATIVE_TAG #define NATIVE_TAG "NativeManager" #endif #include "arkui/ui_input_event.h" namespace NativeOpenCAX { // [Start plugin_manager_cpp] // plugin_manager.cpp std::unordered_map NativeManager::nodeHandleMap_; std::unordered_map NativeManager::callbackMap_; std::unordered_map NativeManager::surfaceHolderMap_; ArkUI_AccessibilityProvider *NativeManager::provider_ = nullptr; ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast( OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); // [StartExclude plugin_manager_cpp] NativeManager NativeManager::pluginManager_; OH_NativeXComponent_Callback NativeManager::xSurfaceTouchEventCallBack; OH_NativeXComponent_MouseEvent_Callback NativeManager::xMouseEventCallBack; std::string comId; std::string nodeId; int32_t NativeManager::hasDraw_ = 0; int32_t NativeManager::hasChangeColor_ = 0; static std::map> renderThreadMap; static std::mutex mapMutex; NativeManager::~NativeManager() { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeManager"); nativeXComponentMap_.clear(); int64_t id = 0; std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) != renderThreadMap.end()) { renderThreadMap[id]->stop(); renderThreadMap.erase(id); } for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) { if (iter->second != nullptr) { delete iter->second; iter->second = nullptr; } } pluginManagerMap_.clear(); } std::string uuid_v4() { // 使用当前时间戳和随机数生成UUID auto timestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count(); std::random_device rd; std::mt19937_64 gen(rd()); std::uniform_int_distribution dis(0, std::numeric_limits::max()); uint64_t random_part = dis(gen); // 合并时间戳和随机数,并转换为UUID格式 uint64_t full_uuid = (timestamp << 32) | (random_part & 0xFFFFFFFF); std::stringstream ss; ss << std::hex << std::uppercase << std::setw(8) << std::setfill('0') << (full_uuid & 0xFFFFFFFF) << "-" << std::setw(4) << std::setfill('0') << (full_uuid >> 32 & 0xFFFF) << "-4" // UUID版本4,中间四位固定为04xx << std::setw(3) << std::setfill('0') << (random_part >> 48 & 0x0FFF | 0x4000) // 设置版本号和一些随机位 << "-" << std::setw(4) << std::setfill('0') << (random_part >> 32 & 0xFFFF) << "-" << std::setw(12) << std::setfill('0') << (random_part & 0xFFFFFFFFFFFF); return ss.str(); } void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) { // [StartExclude plugin_on_surface_created] OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB"); //主动关闭CPU访问窗口缓冲区数据降低功耗 uint64_t usage = 0; int32_t ret2 = OH_NativeWindow_NativeWindowHandleOpt((OHNativeWindow*)window, SET_USAGE, usage); int32_t ret; char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { return; } std::string id(idStr); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB id=%{public}s", id.c_str()); // [EndExclude plugin_on_surface_created] // 初始化环境与绘制背景 auto *pluginManger = NativeManager::GetInstance(); pluginManger->OnSurfaceCreated(component, window); } void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) { // [StartExclude plugin_on_surface_changed] OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceChangedCB"); int32_t ret; char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { return; } std::string id(idStr); // [EndExclude plugin_on_surface_changed] auto *pluginManger = NativeManager::GetInstance(); // 封装OnSurfaceChanged方法 pluginManger->OnSurfaceChanged(component, window); } void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) { // [StartExclude plugin_on_surface_destroyed] OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB"); int32_t ret; char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { return; } std::string id(idStr); // [EndExclude plugin_on_surface_destroyed] auto *pluginManger = NativeManager::GetInstance(); pluginManger->OnSurfaceDestroyed(component, window); } //NativeManager回调 void NativeManager::OnSurfaceCreated(OH_NativeXComponent *component, void *window) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated"); if (!window) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "ERROR: window is NULL in OnSurfaceCreated!"); return; } OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_); int64_t id = 0; std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) == renderThreadMap.end()) { auto renderThread = std::make_shared(); renderThreadMap[id] = renderThread; renderThread->start(reinterpret_cast(window)); } } void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed"); int64_t id = 0; { std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) != renderThreadMap.end()) { renderThreadMap[id]->stop(); renderThreadMap.erase(id); } } } uint64_t width,height; void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) { OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_); int64_t id = 0; { if(width==width_ && height==height_){ return; } std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) != renderThreadMap.end()) { HILOG_ERROR(NATIVE_TAG,"uint32_t Size:%{public}dX%{public}d",width_,height_); renderThreadMap[id]->resizeWindow(width_, height_); width=width_; height=height_; } } } void onEvent(ArkUI_NodeEvent *event) { auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); // 获取组件事件类型 HILOG_ERROR(NATIVE_TAG,"EventType:%{public}d",eventType); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on event"); if (eventType == NODE_TOUCH_EVENT) { ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象 auto holder = NativeManager::surfaceHolderMap_[handle]; EGLCore *render = reinterpret_cast(OH_ArkUI_SurfaceHolder_GetUserData(holder)); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on touch"); } } void OnMouseEventCB(OH_NativeXComponent* component, void* window) { auto* pluginManager = NativeManager::GetInstance(); if (!pluginManager || !window) { return; } auto *pluginManger = NativeManager::GetInstance(); pluginManger->OnMouseEvent(component, window); } void NativeManager::OnMouseEvent(OH_NativeXComponent *comp, void *win) { int32_t ret; OH_NativeXComponent_MouseEvent mouseEvent; ret = OH_NativeXComponent_GetMouseEvent(comp, win, &mouseEvent); if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { return; } OH_NativeXComponent_ExtraMouseEventInfo* extra = NULL; ret = OH_NativeXComponent_GetExtraMouseEventInfo(comp, &extra); if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { return; } //Test Mouse MIDDLE_BUTTON Long Press //HILOG_WARN(NATIVE_TAG, "ExtraMouseEventInfo:%{public}s",extra); std::lock_guard lock(mapMutex); //通过时间戳判断事件唯一性.保证单一时间戳只触发一次事件 if(mouseEvent.timestamp==NativeManager::timestamp){ return; } NativeManager::timestamp=mouseEvent.timestamp; int64_t id = 0; auto it = renderThreadMap.find(id); if (it == renderThreadMap.end()) { HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation."); return; } auto renderThread = it->second; float curtX,curtY; //HILOG_WARN(NATIVE_TAG, "ALLButton:%{public}d",mouseEvent.button); //HILOG_WARN(NATIVE_TAG, "ALLAction:%{public}d",mouseEvent.action); //HILOG_WARN(NATIVE_TAG, "ALLTimestamp:%{public}d",mouseEvent.timestamp); //鼠标按下并且事件为鼠标中键 if(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS){ if(NativeManager::isMouseMiddleBtnPressed){ NativeManager::isMouseMiddleBtnPressed=false; return; } //记录按下时候的X.Y坐标 NativeManager::lastMouseX_=mouseEvent.x; NativeManager::lastMouseY_=mouseEvent.y; NativeManager::isMouseMiddleBtnPressed = true; //HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeManager::lastMouseX_); //HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeManager::lastMouseY_); //HILOG_WARN(NATIVE_TAG, "AtButton:%{public}d",mouseEvent.button); //HILOG_WARN(NATIVE_TAG, "AtButtonAction:%{public}d",mouseEvent.action); //HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed); }else if(mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE&&NativeManager::isMouseMiddleBtnPressed){ // 计算鼠标移动距离 float deltaX = curtX - NativeManager::lastMouseX_; float deltaY = curtY - NativeManager::lastMouseY_; // 将像素移动量映射到旋转角度 // 这里的系数可以根据需要调整灵敏度 float rotationSpeed = 0.001f; float angleX = deltaX * rotationSpeed; float angleY = deltaY * rotationSpeed; // 通知渲染线程执行旋转 // 由于渲染在线程里,需要通过命令队列发送指令 renderThread->setRotation(angleX, angleY); // 更新最后的位置 //NativeManager::lastMouseX_ = deltaX; //NativeManager::lastMouseY_ = deltaY; //HILOG_WARN(NATIVE_TAG, "MoveAngleX:%{public}d",angleX); //HILOG_WARN(NATIVE_TAG, "MoveAngleY:%{public}d",angleY); //HILOG_WARN(NATIVE_TAG, "MoveButton:%{public}d",mouseEvent.button); //HILOG_WARN(NATIVE_TAG, "MoveButtonAction:%{public}d",mouseEvent.action); //HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed); } } static std::string value2String(napi_env env, napi_value value) { size_t stringSize = 0; napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize); std::string valueString; valueString.resize(stringSize); napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize); return valueString; } struct AxisEvent { int32_t axisAction; float displayX; float displayY; std::map axisValues; int64_t actionTime { -1 }; int32_t sourceType; int32_t axisEventType { -1 }; }; // XComponent回调事件 NativeManager::NativeManager() { xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB; xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB; xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB; xMouseEventCallBack.DispatchMouseEvent= OnMouseEventCB; } // 创建节点组件 ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) { nodeId=tag; // 创建Node也名创建ROW Column等容器 ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER); // 节点默认宽度or高度 ArkUI_NumberValue nodeMarginData[] = {{.u32 = 0}, {.f32 = 0}}; // ArkUI_AttributeItem // 参数1:指向数值数组 // 参数2:数组元素个数 // 参数3:属性名(可隐藏) ArkUI_AttributeItem nodeMarginItem = {nodeMarginData, 2}; // 设置Node宽度or高度 nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem); NativeManager::nodeHandleMap_[tag]=nodeHandel; // 创建XComponent组件 // 组件类型Item ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE}; ArkUI_AttributeItem comTypeItem = {comTypeData, 1}; // 组件ID Item comId=uuid_v4(); ArkUI_AttributeItem comIdItem = {.string = comId.c_str(), .size = 1}; // 组件Surface Size // 创建组件 ArkUI_NodeHandle xc; xc = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT); // 设置XComponent组件属性 nodeAPI->setAttribute(xc, NODE_XCOMPONENT_TYPE, &comTypeItem); nodeAPI->setAttribute(xc, NODE_XCOMPONENT_ID, &comIdItem); // 焦点设置 ArkUI_NumberValue focusable[] = {1}; focusable[0].i32 = 1; ArkUI_AttributeItem focusableItem = {focusable, 1}; nodeAPI->setAttribute(xc, NODE_FOCUSABLE, &focusableItem); // 节点ID ArkUI_AttributeItem nodeIdItem = {.string = uuid_v4().c_str(), .size = 1}; nodeAPI->setAttribute(xc, NODE_ID, &nodeIdItem); auto *nativeXComponent = OH_NativeXComponent_GetNativeXComponent(xc); if (!nativeXComponent) { HILOG_ERROR(NATIVE_TAG,"GetNativeXComponent error"); return nodeHandel; } // 注册XComponent回调函数 OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeManager::xSurfaceTouchEventCallBack); //注册XComponent组件鼠标回调事件 OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &NativeManager::xMouseEventCallBack); // nodeAPI->registerNodeEvent(xc, NODE_ON_MOUSE, 1, &xc); // nodeAPI->registerNodeEvent(xc, NODE_ON_AXIS, 1, &xc); // nodeAPI->addNodeEventReceiver(xc, [](ArkUI_NodeEvent *event) { // auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); // auto eventType = OH_ArkUI_UIInputEvent_GetType(inputEvent); // if (OH_ArkUI_NodeEvent_GetEventType(event) == NODE_ON_AXIS ) { // HILOG_WARN(NATIVE_TAG, "NODE_ON_AXIS:%{public}d",OH_ArkUI_NodeEvent_GetEventType(event)); // } // if (eventType == ARKUI_UIINPUTEVENT_TYPE_MOUSE) { // auto action = OH_ArkUI_MouseEvent_GetMouseAction(inputEvent); // auto button= OH_ArkUI_MouseEvent_GetMouseButton(inputEvent); // //HILOG_WARN(NATIVE_TAG, "MouseAction:%{public}d",action); // //HILOG_WARN(NATIVE_TAG, "MouseButton:%{public}d",button); // // int32_t buttonArray[10]; // int32_t arraySize = sizeof(buttonArray) / sizeof(buttonArray[0]); // int32_t actualCount = arraySize; // 将数组大小存入actualCount,作为输入值 // int32_t ret = OH_ArkUI_MouseEvent_GetPressedButtons(inputEvent, buttonArray, &actualCount); // // // --- 步骤 3: 检查API调用结果 --- // if (ret != 0) { // HILOG_WARN(NATIVE_TAG, "Error getting pressed mouse buttons. Error code: %{public}d\n", ret); // return; // } // for (int i = 0; i < actualCount; ++i) { // HILOG_WARN(NATIVE_TAG, "Curt code: %{public}d\n", buttonArray[i]); // // 根据常见的鼠标按钮ID进行解释 (具体ID定义请查阅官方文档) // // 通常 1=主按钮(左键), 2=辅助按钮(右键), 3=中间按钮(滚轮) // switch (buttonArray[i]) { // case 1: HILOG_WARN(NATIVE_TAG, "MouseButton:Left");break; // case 2: HILOG_WARN(NATIVE_TAG, "MouseButton:Right");break; // case 3: HILOG_WARN(NATIVE_TAG, "MouseButton:Middle"); break; // default: printf("(Other_%d) ", buttonArray[i]); break; // } // } // } // }); // 组件类型 auto comTypeRet = nodeAPI->getAttribute(xc, NODE_XCOMPONENT_TYPE); HILOG_INFO(NATIVE_TAG,"XCom type: %{public}d",comTypeRet->value[0].i32); // 组件ID auto comIdRet = nodeAPI->getAttribute(xc, NODE_XCOMPONENT_ID); HILOG_INFO(NATIVE_TAG,"XCom ID: %{public}d",comIdRet->string); // 增加组件到节点 nodeAPI->addChild(nodeHandel, xc); return nodeHandel; } // Native侧创建Node napi_value NativeManager::createNativeNode(napi_env env, napi_callback_info info) { if ((env == nullptr) || (info == nullptr)) { HILOG_ERROR(NATIVE_TAG,"CreateNativeNode env or info is null"); return nullptr; } //获取传入NodeContent实例 size_t argCnt = 1; napi_value args[1] = {nullptr}; if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) { HILOG_ERROR(NATIVE_TAG,"CreateNativeNode napi_get_cb_info failed"); } ArkUI_NodeContentHandle _nodeContentHandle = nullptr; // 获取ArkTS侧创建的NodeContent对象,映射到Native侧的 OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &_nodeContentHandle); // 查询指定的模块接口名 nodeAPI = reinterpret_cast(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); //下面的代码主要用于创建一个Native侧和arkui侧绑定数据的结构传递传输的操作 //node_data可以理解为一个结构体等等之类的指针 // 生成节点名采用NODE_ID_+UUID std::string node_data = uuid_v4(); HILOG_INFO(NATIVE_TAG,"NODE_DATA:%{public}d",node_data.c_str()); // 在NodeContent对象上保存自定义数据。 int32_t ret = OH_ArkUI_NodeContent_SetUserData(_nodeContentHandle, new std::string(node_data)); if (ret != ARKUI_ERROR_CODE_NO_ERROR) { HILOG_ERROR(NATIVE_TAG,"setUserData failed error=%{public}d",ret); } if (nodeAPI != nullptr && nodeAPI->createNode != nullptr && nodeAPI->addChild != nullptr) { auto nodeContentEvent = [](ArkUI_NodeContentEvent *event) { // 获取Node连接事件的对应Node的Handle ArkUI_NodeContentHandle handle = OH_ArkUI_NodeContentEvent_GetNodeContentHandle(event); // 获取对应Handle的UserData std::string *userDate = reinterpret_cast(OH_ArkUI_NodeContent_GetUserData(handle)); if (OH_ArkUI_NodeContentEvent_GetEventType(event) == NODE_CONTENT_EVENT_ON_ATTACH_TO_WINDOW) { ArkUI_NodeHandle testNode; if (userDate) { testNode = CreateNodeHandle(*userDate); delete userDate; userDate = nullptr; } else { testNode = CreateNodeHandle("noUserData"); } // 向NodeContent中添加子组件 OH_ArkUI_NodeContent_AddNode(handle, testNode); } }; OH_ArkUI_NodeContent_RegisterCallback(_nodeContentHandle, nodeContentEvent); } return nullptr; } //设置期望帧率 napi_value NativeManager::SetFrameRate(napi_env env, napi_callback_info info) { size_t argc = 4; napi_value args[4] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string nodeId = value2String(env, args[0]); auto node = nodeHandleMap_[nodeId]; int32_t min = 0; napi_get_value_int32(env, args[FIRST_ARG], &min); int32_t max = 0; napi_get_value_int32(env, args[SECOND_ARG], &max); int32_t expected = 0; napi_get_value_int32(env, args[THIRD_ARG], &expected); OH_NativeXComponent_ExpectedRateRange range = {.min = min, .max = max, .expected = expected}; OH_ArkUI_XComponent_SetExpectedFrameRateRange(node, range); // 设置期望帧率 return nullptr; } napi_value NativeManager::SetNeedSoftKeyboard(napi_env env, napi_callback_info info) { size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string nodeId = value2String(env, args[0]); ArkUI_NodeHandle node; if (nodeHandleMap_.find(nodeId) == nodeHandleMap_.end()) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "SetNeedSoftKeyboard", "nodeId not exit error"); return nullptr; } node = nodeHandleMap_[nodeId]; bool needSoftKeyboard = false; napi_get_value_bool(env, args[1], &needSoftKeyboard); OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard); // 设置是否需要软键盘 return nullptr; } napi_value NativeManager::NapiLoadModel(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string path = value2String(env, args[0]); int64_t id = 0; { std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) != renderThreadMap.end()) { renderThreadMap[id]->loadModel(std::string(path)); } } return nullptr; } //切换视图 napi_value NativeManager::SwitchView(napi_env env, napi_callback_info info){ size_t argc = 1; napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string viewName = value2String(env, args[0]); int64_t id = 0; { std::lock_guard lock(mapMutex); if (renderThreadMap.find(id) != renderThreadMap.end()) { renderThreadMap[id]->swicthView(viewName); } } return nullptr; } //显示模型边界 napi_value NativeManager::displayModelEdges(napi_env env, napi_callback_info info){ } //显示模型线框 napi_value NativeManager::displayHLR(napi_env env, napi_callback_info info){ } //显示隐藏线 napi_value NativeManager::displayHL(napi_env env, napi_callback_info info){ } } // namespace NativeOpenCAX