#include "napi/native_api.h" #include "OCCTRenderThread/OCCTRenderThread.h" #include #include #define LOG_TAG "NAPI_INIT" #define LOGI(...) (LOG_TAG, __VA_ARGS__) //存储 XComponent ID 到 OCCTRenderThread 实例的映射 static std::map g_renderThreads; //NAPI: 初始化渲染器(绑定 XComponent) static napi_value InitRenderer(napi_env env, napi_callback_info info) { size_t argc = 3; napi_value args[3]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // 参数1: xcomponentId (string) char xcompId[256]; size_t xcompIdLen; napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &xcompIdLen); // 参数2: nativeWindow (EGLNativeWindowType, 实际是 void*) EGLNativeWindowType window = nullptr; napi_get_value_external(env, args[1], reinterpret_cast(&window)); // 参数3: { width, height } int32_t width = 0, height = 0; napi_valuetype type; napi_typeof(env, args[2], &type); if (type == napi_object) { napi_value w, h; napi_get_named_property(env, args[2], "width", &w); napi_get_named_property(env, args[2], "height", &h); napi_get_value_int32(env, w, &width); napi_get_value_int32(env, h, &height); } // 创建渲染线程 LOGI('Init RenderThread'); auto* renderThread = new OCCTRenderThread(window, width, height); renderThread->start(); LOGI('Deno Init RenderThread'); g_renderThreads[std::string(xcompId)] = renderThread; return nullptr; } // NAPI: 加载 STEP 模型 static napi_value LoadModel(napi_env env, napi_callback_info info) { LOGI('Start LoadModel'); size_t argc = 2; napi_value args[2]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); char xcompId[256]; size_t len; napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len); char modelPath[1024]; size_t pathLen; napi_get_value_string_utf8(env, args[1], modelPath, sizeof(modelPath), &pathLen); LOGI('Find RenderThread'); auto it = g_renderThreads.find(std::string(xcompId)); if (it != g_renderThreads.end()) { LOGI('LoadModel Began'); it->second->loadModel(modelPath); } return nullptr; } // NAPI: 鼠标/触摸事件(可选,用于旋转) static napi_value OnMouseEvent(napi_env env, napi_callback_info info) { size_t argc = 3; napi_value args[3]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); char xcompId[256]; size_t len; napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len); double dx, dy; napi_get_value_double(env, args[1], &dx); napi_get_value_double(env, args[2], &dy); auto it = g_renderThreads.find(std::string(xcompId)); if (it != g_renderThreads.end()) { it->second->onMouseEvent(static_cast(dx), static_cast(dy)); } return nullptr; } // NAPI: 销毁渲染器 static napi_value DestroyRenderer(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); char xcompId[256]; size_t len; napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len); auto it = g_renderThreads.find(std::string(xcompId)); if (it != g_renderThreads.end()) { it->second->stop(); delete it->second; g_renderThreads.erase(it); } return nullptr; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { if ((env == nullptr) || (exports == nullptr)) { return nullptr; } napi_property_descriptor desc[] = { {"initRenderer", nullptr, InitRenderer,nullptr, nullptr, nullptr, napi_default, nullptr}, {"loadModel", nullptr, LoadModel,nullptr, nullptr, nullptr, napi_default, nullptr}, {"onMouseEvent", nullptr, OnMouseEvent,nullptr, nullptr, nullptr, napi_default, nullptr}, {"destroyRenderer", nullptr, DestroyRenderer,nullptr, nullptr, nullptr, napi_default, nullptr}, }; if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) { return nullptr; } return exports; } EXTERN_C_END // 编写接口的描述信息,根据实际需要可以修改对应参数 static napi_module occtmodel = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "occtrender", .nm_priv = ((void*)0), .reserved = { 0 } }; extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&occtmodel); }