• 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 { generateFunctionDirect } = require("./function_direct");
16const { generateFunctionSync } = require("./function_sync");
17const { generateFunctionAsync } = require("./function_async");
18const { FuncType, InterfaceList, getArrayType } = require("../tools/common");
19const { jsToC } = require("./param_generate");
20const { cToJs } = require("./return_generate");
21const re = require("../tools/re");
22const { NapiLog } = require("../tools/NapiLog");
23
24let middleBodyTmplete = `
25class [className]_middle {
26public:
27    static napi_value constructor(napi_env env, napi_callback_info info)
28    {
29        XNapiTool *pxt = new XNapiTool(env, info);
30
31        [className] *p = new [className]();
32
33        napi_value thisvar = pxt->WrapInstance(p, release);
34
35        return thisvar;
36    }
37    static void release(void *p)
38    {
39        [className] *p2 = ([className] *)p;
40        delete p2;
41    }
42    [static_funcs]
43};`
44
45function generateVariable(name, type, variable, className) {
46    if (type == "string") variable.hDefine += "\n    std::string %s;".format(name)
47    else if (type.substring(0, 12) == "NUMBER_TYPE_") variable.hDefine += "\n    %s %s;".format(type, name)
48    else if (InterfaceList.getValue(type)) variable.hDefine += "\n    %s %s;".format(type, name)
49    else if (type.indexOf("Array<") == 0) {
50        let type2 = getArrayType(type)
51        if (type2 == "string") type2 = "std::string"
52        if (type2 == "boolean") type2 = "bool"
53        variable.hDefine += "\n    std::vector<%s> %s;".format(type2, name)
54    } else if (type == "boolean") {
55        variable.hDefine += "\n    bool %s;".format(name)
56    } else if (type.indexOf("[]") == 0) {
57        variable.hDefine += "\n    std::vector<%s> %s;".format(type, name)
58    }
59    else
60        NapiLog.logError(`
61        ---- generateVariable fail %s,%s ----
62        `.format(name, type));
63    variable.middleValue += `
64    static napi_value getvalue_%s(napi_env env, napi_callback_info info)
65    {
66        XNapiTool *pxt = std::make_unique<XNapiTool>(env, info).release();
67        %s *p = (%s *)pxt->UnWarpInstance();
68        napi_value result = nullptr;
69        `.format(name, className, className) + cToJs("p->" + name, type, "result") + `
70        delete pxt;
71        return result;
72    }
73    static napi_value setvalue_%s(napi_env env, napi_callback_info info)
74    {
75        std::shared_ptr<XNapiTool> pxt = std::make_shared<XNapiTool>(env, info);
76        %s *p = (%s *)pxt->UnWarpInstance();
77        `.format(name, className, className) + jsToC("p->" + name, "pxt->GetArgv(0)", type) + `
78        return nullptr;
79    }
80`
81}
82
83function generateClass(name, data, inNamespace, functiontType) {
84    let resultConnect = connectResult(data, inNamespace, name)
85    let middleFunc = resultConnect[0]
86    let implH = functiontType == "static" ? "\n" + "static " +
87        resultConnect[1].substring(1, resultConnect[1].length) : resultConnect[1]
88    let implCpp = resultConnect[2]
89    let middleInit = resultConnect[3]
90    let selfNs = ""
91    if (inNamespace.length > 0) {
92        let nsl = inNamespace.split("::")
93        nsl.pop()
94        if (nsl.length >= 2) {
95            selfNs = ", " + nsl[nsl.length - 1]
96        }
97    }
98    middleInit += `\n    pxt->DefineClass("%s", %s%s_middle::constructor, valueList ,funcList%s);\n}\n`
99        .format(name, inNamespace, name, selfNs)
100    let result = {
101        implH: `
102class %s {
103public:%s
104};`.format(name, implH),
105        implCpp: implCpp,
106        middleBody: middleBodyTmplete.replaceAll("[className]", name).replaceAll("[static_funcs]", middleFunc),
107        middleInit: middleInit
108    }
109    return result
110}
111
112function connectResult(data, inNamespace, name) {
113    let implH = ""
114    let implCpp = ""
115    let middleFunc = ""
116    let middleInit = ""
117    let variable = {
118        hDefine: "",
119        middleValue: "",
120    }
121    middleInit = `{\n    std::map<const char *,std::map<const char *,napi_callback>> valueList;`
122    for (let i in data.value) {
123        let v = data.value[i]
124        generateVariable(v.name, v.type, variable, name)
125        middleInit += `
126    valueList["%s"]["getvalue"]=%s%s_middle::getvalue_%s;
127    valueList["%s"]["setvalue"]=%s%s_middle::setvalue_%s;`
128            .format(v.name, inNamespace, name, v.name, v.name, inNamespace, name, v.name)
129    }
130    implH += variable.hDefine
131    middleFunc += variable.middleValue
132    middleInit += `\n    std::map<const char *, napi_callback> funcList;`
133    for (let i in data.function) {
134        let func = data.function[i]
135        let tmp;
136        switch (func.type) {
137            case FuncType.DIRECT:
138                tmp = generateFunctionDirect(func, '', name)
139                break;
140            case FuncType.SYNC:
141                tmp = generateFunctionSync(func, '', name)
142                break
143            case FuncType.ASYNC:
144            case FuncType.PROMISE:
145                tmp = generateFunctionAsync(func, '', name)
146                break
147            default:
148                return
149        }
150        middleFunc += tmp[0]
151        implH += tmp[1]
152        implCpp += tmp[2]
153        middleInit += `\n    funcList["%s"] = %s%s_middle::%s_middle;`.format(func.name, inNamespace, name, func.name)
154    }
155    return [middleFunc, implH, implCpp, middleInit]
156}
157
158module.exports = {
159    generateClass
160}