1/* 2* Copyright (c) 2022 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, getPrefix, getConstNum } = require("../tools/tool"); 16const { paramGenerate } = require("./param_generate"); 17const { returnGenerate } = require("./return_generate"); 18 19/** 20 * 结果异步返回Async|Promise 21 */ 22let funcAsyncTemplete = ` 23struct [funcName]_value_struct {[valueIn] 24 uint32_t outErrCode = 0;[valueOut] 25}; 26 27[static_define]void [funcName]_execute(XNapiTool *pxt, DataPtr data) 28{ 29 void *data_ptr = data; 30 [funcName]_value_struct *vio = static_cast<[funcName]_value_struct *>(data_ptr); 31 [checkout_async_instance] 32 [callFunc] 33} 34 35[static_define]void [funcName]_complete(XNapiTool *pxt, DataPtr data) 36{ 37 void *data_ptr = data; 38 [funcName]_value_struct *vio = static_cast<[funcName]_value_struct *>(data_ptr); 39 napi_value result = nullptr; 40 [valuePackage] 41 napi_value errCodeResult = nullptr; 42 napi_value napiErrCode = nullptr; 43 napiErrCode = NUMBER_C_2_JS(pxt, vio->outErrCode); 44 pxt->SetValueProperty(errCodeResult, "code", napiErrCode); 45 { 46 napi_value args[XNapiTool::TWO] = {errCodeResult, result}; 47 pxt->FinishAsync(XNapiTool::TWO, args); 48 } 49 [optionalParamDestory] 50 delete vio; 51} 52 53[static_define]napi_value [funcName]_middle(napi_env env, napi_callback_info info) 54{ 55 XNapiTool *pxt = std::make_unique<XNapiTool>(env, info).release(); 56 if (pxt->IsFailed()) { 57 napi_value err = pxt->GetError(); 58 delete pxt; 59 return err; 60 } 61 [unwarp_instance] 62 struct [funcName]_value_struct *vio = new [funcName]_value_struct(); 63 [valueCheckout][optionalCallbackInit][start_async] 64 if (pxt->IsFailed()) { 65 result = pxt->GetError(); 66 } 67 return result; 68}` 69 70let cppTemplate = ` 71bool %s%s(%s) 72{ 73 return true; 74} 75` 76 77function removeEndlineEnter(value) { 78 for (var i = value.length; i > 0; i--) { 79 let len = value.length 80 if (value.substring(len - 1, len) == "\n" || value.substring(len - 1, len) == ' ') { 81 value = value.substring(0, len - 1) 82 } else { 83 value = ' ' + value + "\n" 84 break 85 } 86 } 87 return value 88} 89 90function getOptionalCallbackInit(param) { 91 if (!param.callback.optional) { 92 return "" 93 } 94 let cType = param.valueOut.substr(0, param.valueOut.indexOf("*")) 95 return "vio->out = new %s;".format(cType) 96} 97 98function replaceBasicInfo(middleFunc, className) { 99 if (className == null) { 100 middleFunc = middleFunc.replaceAll("[static_define]", "") 101 middleFunc = middleFunc.replaceAll("[unwarp_instance]", "") 102 middleFunc = middleFunc.replaceAll("[checkout_async_instance]", "") 103 } 104 else { 105 middleFunc = middleFunc.replaceAll("[static_define]", "static ") 106 middleFunc = middleFunc.replaceAll("[unwarp_instance]", 107 `pxt->SetAsyncInstance(pxt->UnWarpInstance());`) 108 middleFunc = middleFunc.replaceAll("[checkout_async_instance]", 109 "%s *pInstance = (%s *)pxt->GetAsyncInstance();".format(className, className)) 110 } 111 return middleFunc 112} 113function generateFunctionAsync(func, data, className) { 114 let middleFunc = replaceAll(funcAsyncTemplete, "[funcName]", func.name) 115 middleFunc = replaceBasicInfo(middleFunc, className) 116 117 // 定义输入,定义输出,解析,填充到函数内,输出参数打包,impl参数定义,可选参数内存释放 118 let param = { valueIn: "", valueOut: "", valueCheckout: "", valueFill: "", 119 valuePackage: "", valueDefine: "", optionalParamDestory: "" } 120 121 for (let i in func.value) { 122 paramGenerate(i, func.value[i], param, data) 123 } 124 returnGenerate(param.callback, param, data) 125 126 middleFunc = replaceAll(middleFunc, "[valueIn]", param.valueIn) // # 输入参数定义 127 if (param.valueOut == "") { 128 middleFunc = replaceAll(middleFunc, "[valueOut]", param.valueOut) // # 输出参数定义 129 } else { 130 middleFunc = replaceAll(middleFunc, "[valueOut]", "\n " + param.valueOut) // # 输出参数定义 131 } 132 if (param.valueCheckout == "") { 133 middleFunc = replaceAll(middleFunc, "[valueCheckout]", param.valueCheckout) // # 输入参数解析 134 } else { 135 param.valueCheckout = removeEndlineEnter(param.valueCheckout) 136 middleFunc = replaceAll(middleFunc, "[valueCheckout]", param.valueCheckout) // # 输入参数解析 137 } 138 let optionalCallback = getOptionalCallbackInit(param) 139 if (optionalCallback == "") { 140 middleFunc = replaceAll(middleFunc, "[optionalCallbackInit]", optionalCallback) // 可选callback参数初始化 141 } else { 142 middleFunc = replaceAll(middleFunc, "[optionalCallbackInit]", optionalCallback + "\n ") // 可选callback参数初始化 143 } 144 middleFunc = replaceAll(middleFunc, "[start_async]", ` 145 napi_value result = pxt->StartAsync(%s_execute, reinterpret_cast<DataPtr>(vio), %s_complete, 146 pxt->GetArgc() == %s? pxt->GetArgv(%d) : nullptr);` 147 .format(func.name, func.name, getConstNum(parseInt(param.callback.offset) + 1), 148 getConstNum(param.callback.offset))) // 注册异步调用 149 let callFunc = "%s%s(%s);".format(className == null ? "" : "pInstance->", func.name, param.valueFill) 150 middleFunc = replaceAll(middleFunc, "[callFunc]", callFunc) // 执行 151 middleFunc = replaceAll(middleFunc, "[valuePackage]", param.valuePackage) // 输出参数打包 152 middleFunc = replaceAll(middleFunc, "[optionalParamDestory]", param.optionalParamDestory) // 可选参数内存释放 153 154 let prefixArr = getPrefix(data, func) 155 let implH = "" 156 let implCpp = "" 157 if (!func.isParentMember) { 158 // 只有类/接口自己的成员方法需要在.h.cpp中生成,父类/父接口不需要 159 implH = "\n%s%s%sbool %s(%s)%s;".format( 160 prefixArr[0], prefixArr[1], prefixArr[2], func.name, param.valueDefine, prefixArr[3]) 161 implCpp = cppTemplate.format(className == null ? "" : className + "::", func.name, param.valueDefine) 162 } 163 return [middleFunc, implH, implCpp] 164} 165 166module.exports = { 167 generateFunctionAsync 168}