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