• 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');
18const { jsonCfgList, InterfaceList, CallFunctionList } = require('../tools/common');
19const { NapiLog } = require('../tools/NapiLog');
20
21/**
22 * 结果直接返回
23 */
24let funcDirectMiddleHTemplete = `
25struct [funcName]_value_struct {[valueIn][valueOut]
26};
27
28[static_define]napi_value [funcName]_middle(napi_env env, napi_callback_info info);
29`;
30
31let funcDirectTemplete = `
32napi_value [middleClassName][funcName]_middle(napi_env env, napi_callback_info info)
33{
34    XNapiTool *pxt = std::make_unique<XNapiTool>(env, info).release();
35    if (pxt->IsFailed()) {
36        napi_value err = pxt->GetError();
37        delete pxt;
38        return err;
39    }
40    [unwarp_instance]
41    struct [funcName]_value_struct *vio = new [funcName]_value_struct();
42    [valueCheckout]
43    [addListener]
44    [callFunc]
45    napi_value result = nullptr;
46    [valuePackage][optionalParamDestory]
47    delete vio;
48    delete pxt; // release
49    return result;
50}`;
51
52let cppTemplate = `
53%s
54bool %s%s(%s)
55{
56    %s
57    return true;
58}
59`;
60
61function removeEndlineEnter(value) {
62    for (let i = value.length; i > 0; i--) {
63        let len = value.length;
64        if (value.substring(len - 1, len) === '\n' || value.substring(len - 1, len) === ' ') {
65            value = value.substring(0, len - 1);
66        } else {
67            value = '    ' + value;
68            break;
69        }
70    }
71    return value;
72}
73
74function isAddFunc(name) {
75    let regIndex = name.indexOf('add');
76    let flag = false;
77    if (regIndex === 0) {
78        flag = true;
79    }
80    return flag;
81}
82
83function isRemoveFunc(name) {
84    let regIndex = name.indexOf('remove');
85    let flag = false;
86    if (regIndex === 0) {
87        flag = true;
88    }
89    return flag;
90}
91
92function getaddListenerCont() {
93    let addListenerCont = `napi_value para = pxt->GetArgv(XNapiTool::ZERO);
94    napi_valuetype valueType = napi_undefined;
95    napi_status status = napi_typeof(env, para, &valueType);
96    if (status != napi_ok) {
97        return nullptr;
98    }
99    if (valueType !=  napi_object) {
100       printf("valueType is Err, not napi_object !");
101       return nullptr;
102    }
103
104    std::vector<std::string> proNames;
105    std::string prefixName = "%s";
106    std::string proNameReg = "";
107    std::string proName = "";
108    [getProNames]
109    for(size_t i=0; i<proNames.size(); i++) {
110    proName = proNames[i];
111    printf("proName is: %s! ", proName.c_str());
112     bool hasProperty = false;
113     napi_value cbFunc = nullptr;
114     napi_has_named_property(env, para, proName.c_str(), &hasProperty);
115     if (hasProperty) {
116         printf("hasProperty is true! ");
117         napi_value propKey = nullptr;
118         napi_create_string_utf8(env, proName.c_str(), proName.length(), &propKey);
119         napi_get_property(env, para, propKey, &cbFunc);
120         if (cbFunc != nullptr) {
121            proNameReg = prefixName + "_" + proName;
122            printf("proNameReg is %s  ", proNameReg.c_str());
123            [RegistOrUnregistFunc]
124         }
125     }
126    }`;
127    return addListenerCont;
128}
129
130//(InterfaceList.getValue(type)) 判断func value是否为interface
131//是的话,读callfunction 根据 interfaceName过滤得到所有回调的名称,填到Add处理中
132// add处理根据名称集检查当前实例对象是否存在此回调,存在则注册,否则不处理
133function getAddOrRemoveReg(func, isAddReg) {
134    let addListenerCont = '';
135    const addParaSize = 1;
136    if (func.value.length !== addParaSize) {
137        NapiLog.logError(`AddReg param do not support param number not 1!`);
138        return '';
139    }
140
141    let ValueType = func.value[0].type;
142    let funNames = [];
143    if (InterfaceList.getValue(ValueType)) {
144        let cbFuncTypePrefix = 'AUTO_CALLFUNCTION_' + ValueType;
145        funNames = CallFunctionList.getObjOnFuncName(cbFuncTypePrefix);
146    }
147
148    addListenerCont = getaddListenerCont();
149    let proNamesValues = '';
150    for (let i = 0; i < funNames.length; i++) {
151        proNamesValues += 'proNames.push_back("%s");\r\n'.format(funNames[i]);
152    }
153    addListenerCont = replaceAll(addListenerCont, '[getProNames]', proNamesValues);
154    addListenerCont = addListenerCont.format(ValueType);
155
156    let registOrUnregis = '';
157    if (isAddReg) {
158        registOrUnregis = 'pxt->RegistOnOffFunc(proNameReg, cbFunc);';
159    } else {
160        registOrUnregis = 'pxt->UnregistOnOffFunc(proNameReg);';
161    }
162    addListenerCont = replaceAll(addListenerCont, '[RegistOrUnregistFunc]', registOrUnregis);
163    return addListenerCont;
164}
165
166function replaceOptionalParamDestory(middleFunc, param) {
167    if (param.optionalParamDestory === '') {
168        middleFunc = replaceAll(middleFunc, '[optionalParamDestory]', param.optionalParamDestory); // 可选参数内存释放
169    } else {
170        middleFunc = replaceAll(middleFunc, '[optionalParamDestory]', '\n    ' + param.optionalParamDestory); // 可选参数内存释放
171    }
172    return middleFunc;
173}
174
175function generateFunctionDirect(func, data, className, implHVariable) {
176    let middleFunc = replaceAll(funcDirectTemplete, '[funcName]', func.name);
177    let middleH = '';
178    if (func.name !== 'constructor') {
179        middleH = replaceAll(funcDirectMiddleHTemplete, '[funcName]', func.name);
180    }
181
182    let isAddReg = isAddFunc(func.name);
183    let isRemoveReg = isRemoveFunc(func.name);
184    let addListenerCont = '';
185    if (isAddReg || isRemoveReg) {
186        addListenerCont = getAddOrRemoveReg(func, isAddReg);
187    }
188    middleFunc = replaceAll(middleFunc, '[addListener]', addListenerCont);
189
190    let isClassresult = isClassFunc(className, middleFunc, middleH);
191    middleFunc = isClassresult[0];
192    middleH = isClassresult[1];
193    // 定义输入,定义输出,解析,填充到函数内,输出参数打包,impl参数定义,可选参数内存释放
194    let param = {
195        valueIn: '', valueOut: '', valueCheckout: '', valueFill: '',
196        valuePackage: '', valueDefine: '', optionalParamDestory: ''
197    };
198
199    for (let i in func.value) {
200        paramGenerate(i, func.value[i], param, data);
201    }
202    let returnInfo = { type: func.ret, optional: false };
203    if (func.ret === 'void') {
204        param.valuePackage = 'result = pxt->UndefinedValue();';
205    } else {
206        returnGenerate(returnInfo, param, data);
207    }
208    middleH = replaceValueOut(middleH, param);
209
210    param.valueCheckout = removeEndlineEnter(param.valueCheckout);
211    middleFunc = replaceAll(middleFunc, '[valueCheckout]', param.valueCheckout); // # 输入参数解析
212    let callFunc = '%s%s(%s);'.format(className === null || className === undefined ? '' : 'pInstance->',
213        func.name, param.valueFill);
214    middleFunc = replaceAll(middleFunc, '[callFunc]', callFunc); // 执行
215    middleFunc = replaceAll(middleFunc, '[valuePackage]', param.valuePackage); // 输出参数打包
216    middleFunc = replaceOptionalParamDestory(middleFunc, param);
217    let prefixArr = getPrefix(data, func);
218    let implH = '';
219    let implCpp = '';
220
221    if (!func.isParentMember) {
222        if (func.name === 'constructor') {
223            // 构造函数去掉&或* (在内部去掉较麻烦,生成后统一去除)
224            implH = constructorFunc(param, implHVariable, implH, prefixArr, className);
225            middleFunc = '';
226        } else {
227            // 只有类/接口自己的成员方法需要在.h.cpp中生成,父类/父接口不需要
228            implH = getimplHForForComClassValue(isAddReg, param, prefixArr, func);
229            implCpp = getimplCppForComClassValue(isAddReg, param, className, func);
230        }
231    }
232    return [middleFunc, implH, implCpp, middleH];
233}
234
235function getimplHForForComClassValue(isAddReg, param, prefixArr, func) {
236    let implH = '\n%s%s%sbool %s(%s)%s;'.format(
237        prefixArr[0], prefixArr[1], prefixArr[2], func.name, param.valueDefine, prefixArr[3]);
238
239    if (isAddReg) {
240        let ValueType = func.value[0].type;
241        implH += '\n    static %s listener_;'.format(ValueType);
242    }
243    return implH;
244}
245
246function getimplCppForComClassValue(isAddReg, param, className, func) {
247    let implCpp = '';
248    let initListener = '';
249    let callStatement = jsonCfgList.getValue((className === null || className === undefined) ?
250        '' : className, func.name);
251
252    if (isAddReg) {
253        initListener = '%s %s::listener_ = {};'.format(func.value[0].type, className);
254        callStatement = '%s::listener_ = listener;'.format(className);
255    }
256
257    implCpp = cppTemplate.format(initListener, (className === null || className === undefined) ?
258        '' : className + '::', func.name,
259        param.valueDefine, (callStatement === null || callStatement === undefined) ? '' : callStatement);
260    return implCpp;
261}
262
263function replaceValueOut(middleH, param) {
264    middleH = replaceAll(middleH, '[valueIn]', param.valueIn); // # 输入参数定义
265    if (param.valueOut === '') {
266        middleH = replaceAll(middleH, '[valueOut]', param.valueOut); // # 输出参数定义
267    } else {
268        middleH = replaceAll(middleH, '[valueOut]', '\n    ' + param.valueOut); // # 输出参数定义
269    }
270    return middleH;
271}
272
273function isClassFunc(className, middleFunc, middleH) {
274    if (className === null || className === undefined) {
275        middleH = middleH.replaceAll('[static_define]', '');
276        middleFunc = middleFunc.replaceAll('[unwarp_instance]', '');
277        middleFunc = middleFunc.replaceAll('[middleClassName]', '');
278    }
279    else {
280        middleH = middleH.replaceAll('[static_define]', 'static ');
281        middleFunc = middleFunc.replaceAll('[unwarp_instance]',
282            `void *instPtr = pxt->UnWarpInstance();
283    %s *pInstance = static_cast<%s *>(instPtr);`.format(className, className));
284        middleFunc = middleFunc.replaceAll('[middleClassName]', className + '_middle' + '::');
285    }
286    return [middleFunc, middleH];
287}
288
289function constructorFunc(param, implHVariable, implH, prefixArr, className) {
290    let valueDef = param.valueDefine;
291    if (valueDef.indexOf('&') > 0 || valueDef.indexOf('*') > 0) {
292        let index = valueDef.indexOf('&');
293        while (index > 0) {
294            valueDef = valueDef.substring(0, index) + valueDef.substring(index + 1, valueDef.length);
295            index = valueDef.indexOf('&');
296        }
297        index = valueDef.indexOf('*');
298        while (index > 0) {
299            valueDef = valueDef.substring(0, index) + valueDef.substring(index + 1, valueDef.length);
300            index = valueDef.indexOf('*');
301        }
302    }
303    let body = valueDef.split(',');
304    let result = [];
305    let body2 = implHVariable.split(';');
306    let result2 = [];
307    for (let i = 0; i < body.length; i++) {
308        let ii = body[i].lastIndexOf(' ');
309        result[i] = body[i].substring(ii + 1, body[i].length);
310    }
311    for (let k = 0; k < body2.length; k++) {
312        let kk = body2[k].lastIndexOf(' ');
313        result2[k] = body2[k].substring(kk + 1, body2[k].length);
314    }
315    let len = result.length;
316    let costructorStr = '';
317    for (let m = 0; m < len - 1; m++) {
318        costructorStr += '%s(%s), '.format(result2[m], result[m]);
319    }
320    costructorStr += '%s(%s)'.format(result2[len - 1], result[len - 1]);
321
322    // 构造函数只在h文件中,cpp文件中不包含
323    if (len > 0) {
324        implH = '\n%s%s%s%s() {};'.format(
325            prefixArr[0], prefixArr[1], prefixArr[2], className);
326        implH += '\n%s%s%s%s(%s) : %s {};'.format(
327            prefixArr[0], prefixArr[1], prefixArr[2], className, valueDef, costructorStr);
328    } else {
329        implH = '\n%s%s%s%s() {};'.format(
330            prefixArr[0], prefixArr[1], prefixArr[2], className);
331    }
332    return implH;
333}
334
335module.exports = {
336    generateFunctionDirect
337};