2023-05-04 15:00:22 +00:00
|
|
|
// Run with Node.js
|
|
|
|
|
|
|
|
const fs = require('fs');
|
2023-05-04 21:54:03 +00:00
|
|
|
const { connect } = require('http2');
|
|
|
|
let api, modules
|
2023-05-04 15:00:22 +00:00
|
|
|
|
|
|
|
async function main(){
|
|
|
|
api = await readJson('thirdparty/raylib/parser/output/raylib_api.json')
|
2023-05-04 21:54:03 +00:00
|
|
|
modules = await readJson('bindings.json')
|
2023-05-04 15:00:22 +00:00
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
const headers = modules.map(generateModule)
|
2023-05-04 15:00:22 +00:00
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
modules.forEach(async (header,i) => {
|
|
|
|
await writeFile(`src/bindings/js_${header.name}.h`, headers[i])
|
2023-05-04 15:00:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
class FunctionList {
|
|
|
|
definitions = []
|
|
|
|
|
2023-05-04 15:05:36 +00:00
|
|
|
addFunctionDef(name, args, cname){
|
2023-05-04 21:54:03 +00:00
|
|
|
this.definitions.push(`JS_CFUNC_DEF("${name}", ${args}, ${cname})`)
|
2023-05-04 15:05:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
addIntConst(name, val){
|
|
|
|
this.definitions.push(`JS_PROP_INT32_DEF("${name}", ${val})`)
|
2023-05-04 15:00:22 +00:00
|
|
|
}
|
2023-05-04 21:54:03 +00:00
|
|
|
|
|
|
|
generate(name){
|
|
|
|
return `static const JSCFunctionListEntry js_${name}_funcs[] = {
|
|
|
|
${this.definitions.map(x => " "+x).join(",\n")}
|
|
|
|
};`
|
|
|
|
}
|
2023-05-04 15:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const generateModule = (mod) => {
|
2023-05-04 21:54:03 +00:00
|
|
|
const fl = new FunctionList()
|
|
|
|
let content = mod.functions.map(generateFunction(fl)).join("\n\n")
|
|
|
|
content += "\n\n" + fl.generate(mod.name)
|
|
|
|
return generateHeader(mod.name, content)
|
2023-05-04 15:00:22 +00:00
|
|
|
}
|
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
const generateFunction = (functionList) => (func) => {
|
2023-05-04 15:00:22 +00:00
|
|
|
const api = findFunction(func.name)
|
2023-05-04 21:54:03 +00:00
|
|
|
const cfunc = new CFunction(func, api, functionList)
|
|
|
|
return cfunc.generate()
|
|
|
|
}
|
|
|
|
|
|
|
|
const generateParameter = (param,i) => {
|
|
|
|
switch(param.type){
|
|
|
|
case "const char *":
|
|
|
|
return `${param.type} ${param.name} = JS_ToCString(ctx, argv[${i}]);`
|
|
|
|
case "int":
|
|
|
|
return `${param.type} ${param.name};\n JS_ToInt32(ctx, &${param.name}, argv[${i}]);`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class CFunction {
|
|
|
|
constructor(func, api, functionList){
|
|
|
|
this.func = func
|
|
|
|
this.api = api
|
|
|
|
this.functionList = functionList
|
|
|
|
this.functionName = `js_${func.jsName}`
|
|
|
|
}
|
|
|
|
|
|
|
|
generateParameters(){
|
|
|
|
return this.api.params.map(generateParameter)
|
|
|
|
}
|
|
|
|
|
|
|
|
generate(){
|
|
|
|
this.functionList.addFunctionDef(this.func.jsName, this.api.params.length, this.functionName)
|
|
|
|
return `static JSValue ${this.functionName}(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){
|
|
|
|
${this.generateParameters().map(x => " "+x).join("\n")}
|
|
|
|
return JS_UNDEFINED;
|
|
|
|
}`
|
|
|
|
}
|
2023-05-04 15:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const findFunction = (name) => findIn(api.functions,name)
|
|
|
|
|
|
|
|
const findIn = (arr, name) => arr.find(x => x.name == name)
|
|
|
|
|
|
|
|
|
|
|
|
async function readJson(path){
|
|
|
|
const c = await readFile(path)
|
|
|
|
return JSON.parse(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
function readFile(path) {
|
|
|
|
const p = new Promise((res,rej) => {
|
|
|
|
fs.readFile(path, 'utf8', (err,data) => {
|
|
|
|
if(err) rej(error)
|
|
|
|
else res(data)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
function writeFile(path, data){
|
|
|
|
return new Promise((res, rej) => {
|
|
|
|
fs.writeFile(path, data, (err) => {
|
|
|
|
if(err) rej(err)
|
|
|
|
else res()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
function generateHeader(name, content){
|
|
|
|
return `
|
2023-05-04 15:00:22 +00:00
|
|
|
#ifndef JS_${name}
|
|
|
|
#define JS_${name}
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <quickjs.h>
|
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
#ifndef countof
|
|
|
|
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
#endif
|
|
|
|
|
2023-05-04 15:00:22 +00:00
|
|
|
${content}
|
|
|
|
|
|
|
|
static int js_${name}_init(JSContext *ctx, JSModuleDef *m){
|
|
|
|
JS_SetModuleExportList(ctx, m, js_${name}_funcs,
|
|
|
|
countof(js_${name}_funcs));
|
|
|
|
}
|
|
|
|
|
|
|
|
JSModuleDef *js_init_module_${name}(JSContext *ctx, const char *module_name)
|
|
|
|
{
|
|
|
|
JSModuleDef *m;
|
|
|
|
m = JS_NewCModule(ctx, module_name, js_${name}_init);
|
|
|
|
if (!m)
|
|
|
|
return NULL;
|
|
|
|
|
2023-05-04 21:54:03 +00:00
|
|
|
JS_AddModuleExportList(ctx, m, js_${name}_funcs,
|
|
|
|
countof(js_${name}_funcs));
|
|
|
|
|
2023-05-04 15:00:22 +00:00
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
`
|
|
|
|
}
|
|
|
|
|
|
|
|
main()
|