• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}