OpenCAX/entry/src/main/cpp/NativeEGLOCCT/NativeManager.cpp
JackLee 818662eb96 封装Native侧得OCCT类和对象.
归一化视角切换函数和实现.
修复最大化窗口渲染同步失败问题.
增加模型边界线显示
Next Version:
增加线框,隐藏线框,等功能
2026-03-23 20:29:18 +08:00

527 lines
23 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "NativeManager.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <cstdint>
#include <cstdio>
#include <hilog/log.h>
#include <string>
#include "arkui/native_node.h"
#include "arkui/native_node_napi.h"
#include "arkui/native_interface.h"
#include "common.h"
#include <random>
#include <map>
#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<std::string, ArkUI_NodeHandle> NativeManager::nodeHandleMap_;
std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> NativeManager::callbackMap_;
std::unordered_map<void *, OH_ArkUI_SurfaceHolder *> NativeManager::surfaceHolderMap_;
ArkUI_AccessibilityProvider *NativeManager::provider_ = nullptr;
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
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<int64_t, std::shared_ptr<NativeRenderThread>> 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<std::mutex> 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<uint64_t> dis(0, std::numeric_limits<uint64_t>::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<std::mutex> lock(mapMutex);
if (renderThreadMap.find(id) == renderThreadMap.end()) {
auto renderThread = std::make_shared<NativeRenderThread>();
renderThreadMap[id] = renderThread;
renderThread->start(reinterpret_cast<OHNativeWindow*>(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<std::mutex> 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<std::mutex> 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<EGLCore *>(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<std::mutex> 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<int32_t, double> 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<ArkUI_NativeNodeAPI_1 *>(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<std::string *>(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<std::mutex> 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<std::mutex> 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