1/* 2* Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15const { replaceAll } = require('../tools/tool'); 16const re = require('../tools/re'); 17 18let middleHTdSafeFuncTemplate = ` 19struct createThreadSafeFunc[funcName]_value_struct { 20 std::string eventName; 21}; 22 23[static_define] napi_value createThreadSafeFunc[funcName]_middle(napi_env env, napi_callback_info info); 24`; 25 26/** 27 * ThreadsafeFunc接口生成模板 28 */ 29let threadsafeFuncTemplete = ` 30void threadSafeFuncCallJs[funcName](napi_env env, napi_value jsCallback, void *context, void *data) 31{ 32 // to add user CallJs code 33} 34napi_value [middleClassName]createThreadSafeFunc[funcName]_middle(napi_env env, napi_callback_info info) 35{ 36 XNapiTool *pxt = std::make_unique<XNapiTool>(env, info).release(); 37 if (pxt->IsFailed()) { 38 napi_value err = pxt->GetError(); 39 delete pxt; 40 return err; 41 } 42 struct createThreadSafeFunc[funcName]_value_struct *vio = new createThreadSafeFunc[funcName]_value_struct(); 43 44 const size_t argc = pxt->GetArgc(); 45 46 // 获取第一个参数,线程安全函数名称 get ThreadSafeFunc name 47 pxt->SwapJs2CUtf8(pxt->GetArgv(XNapiTool::ZERO), vio->eventName); 48 49 // 判断最后一个参数是否为回调函数类型 50 napi_valuetype valueType = napi_undefined; 51 napi_status status = napi_typeof(env, pxt->GetArgv(argc - 1), &valueType); 52 if (status != napi_ok) { 53 return nullptr; 54 } 55 if (valueType != napi_function) { 56 printf("valueType is Err, not napi_function!"); 57 return nullptr; 58 } 59 60 // create ThreadSafeFunc 61 napi_threadsafe_function threadsafeFunc; 62 const size_t maxQueueSize = 0; // 0 means no limited 63 const size_t initialThreadCount = 1; 64 napi_value name = pxt->GetArgv(XNapiTool::ZERO); //资源名称复用线程安全函数名称 65 status = napi_create_threadsafe_function(env, pxt->GetArgv(argc - 1), nullptr, 66 name, maxQueueSize, initialThreadCount, nullptr, nullptr, nullptr, threadSafeFuncCallJs[funcName], &threadsafeFunc); 67 if (status != napi_ok) { 68 return nullptr; 69 } 70 pxt->RegistThreadsafeFunc(vio->eventName, threadsafeFunc); 71 XNapiTool::CallThreadSafeFunc(vio->eventName); 72 napi_value result = pxt->UndefinedValue(); 73 delete vio; 74 delete pxt; // release 75 return result; 76} 77`; 78 79function generateThreadsafeFunc(func, data, className) { 80 let codeContext = { 81 middleFunc: '', 82 implH: '', 83 implCpp: '', 84 middleH: '' 85 }; 86 87 let name = func.name; 88 let preFix = 'createThreadSafeFunc'; 89 90 let postFix = name.substring(preFix.length, name.length); 91 codeContext.middleFunc = replaceAll(threadsafeFuncTemplete, '[funcName]', postFix); 92 codeContext.middleH = replaceAll(middleHTdSafeFuncTemplate, '[funcName]', postFix); 93 let middleClassName = ''; 94 if (className === null || className === undefined) { 95 codeContext.middleH = codeContext.middleH.replaceAll('[static_define]', ''); 96 codeContext.middleFunc = codeContext.middleFunc.replaceAll('[middleClassName]', ''); 97 } 98 else { 99 middleClassName = className + '_middle'; 100 codeContext.middleH = codeContext.middleH.replaceAll('[static_define]', 'static '); 101 codeContext.middleFunc = codeContext.middleFunc.replaceAll('[middleClassName]', middleClassName + '::'); 102 } 103 104 return [codeContext.middleFunc, codeContext.implH, codeContext.implCpp, codeContext.middleH]; 105} 106 107module.exports = { 108 generateThreadsafeFunc 109}; 110