diff --git a/bindings.json b/bindings.json index ff10457..13ceb9a 100644 --- a/bindings.json +++ b/bindings.json @@ -1,8 +1,9 @@ [ { - "header": "raylib_core", + "name": "raylib_core", "functions": [ - { "name": "SetWindowTitle", "jsName": "setWindowTitle" } + { "name": "SetWindowTitle", "jsName": "setWindowTitle" }, + { "name": "SetWindowPosition", "jsName": "setWindowPosition" } ] } ] \ No newline at end of file diff --git a/generate_bindings.js b/generate_bindings.js index 866d25c..2a8e1f6 100644 --- a/generate_bindings.js +++ b/generate_bindings.js @@ -1,16 +1,17 @@ // Run with Node.js const fs = require('fs'); -let api, bindings +const { connect } = require('http2'); +let api, modules async function main(){ api = await readJson('thirdparty/raylib/parser/output/raylib_api.json') - bindings = await readJson('bindings.json') + modules = await readJson('bindings.json') - const headers = bindings.map(generateModule) + const headers = modules.map(generateModule) - bindings.forEach(async (header,i) => { - await writeFile(`js_${header.header}.h`, headers[i]) + modules.forEach(async (header,i) => { + await writeFile(`src/bindings/js_${header.name}.h`, headers[i]) }); } @@ -18,20 +19,61 @@ class FunctionList { definitions = [] addFunctionDef(name, args, cname){ - this.definitions.push(`JS_FUNC_DEF("${name}", ${args}, ${cname})`) + this.definitions.push(`JS_CFUNC_DEF("${name}", ${args}, ${cname})`) } addIntConst(name, val){ this.definitions.push(`JS_PROP_INT32_DEF("${name}", ${val})`) } + + generate(name){ + return `static const JSCFunctionListEntry js_${name}_funcs[] = { +${this.definitions.map(x => " "+x).join(",\n")} +};` + } } const generateModule = (mod) => { - + 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) } -const generateFunction = (func) => { +const generateFunction = (functionList) => (func) => { const api = findFunction(func.name) + 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; +}` + } } const findFunction = (name) => findIn(api.functions,name) @@ -63,8 +105,8 @@ function writeFile(path, data){ }) } -function templateHeader(name, content){ - const res = ` +function generateHeader(name, content){ + return ` #ifndef JS_${name} #define JS_${name} @@ -74,6 +116,10 @@ function templateHeader(name, content){ #include +#ifndef countof +#define countof(x) (sizeof(x) / sizeof((x)[0])) +#endif + ${content} static int js_${name}_init(JSContext *ctx, JSModuleDef *m){ @@ -88,6 +134,9 @@ JSModuleDef *js_init_module_${name}(JSContext *ctx, const char *module_name) if (!m) return NULL; + JS_AddModuleExportList(ctx, m, js_${name}_funcs, + countof(js_${name}_funcs)); + return m; } diff --git a/main.js b/main.js index 64f2d4a..10e92a7 100644 --- a/main.js +++ b/main.js @@ -1,9 +1,5 @@ -import { test } from "./my-module.js"; +import { setWindowTitle } from "raylib.core" -console.log(test()) +console.log(setWindowTitle("Test")) -async function main(){ - await Promise.resolve() - console.log("Test") -} diff --git a/src/bindings/js_raylib_core.h b/src/bindings/js_raylib_core.h new file mode 100644 index 0000000..7fbec86 --- /dev/null +++ b/src/bindings/js_raylib_core.h @@ -0,0 +1,52 @@ + +#ifndef JS_raylib_core +#define JS_raylib_core + +#include +#include +#include + +#include + +#ifndef countof +#define countof(x) (sizeof(x) / sizeof((x)[0])) +#endif + +static JSValue js_setWindowTitle(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){ + const char * title = JS_ToCString(ctx, argv[0]); + return JS_UNDEFINED; +} + +static JSValue js_setWindowPosition(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){ + int x; + JS_ToInt32(ctx, &x, argv[0]); + int y; + JS_ToInt32(ctx, &y, argv[1]); + return JS_UNDEFINED; +} + +static const JSCFunctionListEntry js_raylib_core_funcs[] = { + JS_CFUNC_DEF("setWindowTitle", 1, js_setWindowTitle), + JS_CFUNC_DEF("setWindowPosition", 2, js_setWindowPosition) +}; + +static int js_raylib_core_init(JSContext *ctx, JSModuleDef *m){ + JS_SetModuleExportList(ctx, m, js_raylib_core_funcs, + countof(js_raylib_core_funcs)); +} + +JSModuleDef *js_init_module_raylib_core(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_raylib_core_init); + if (!m) + return NULL; + + JS_AddModuleExportList(ctx, m, js_raylib_core_funcs, + countof(js_raylib_core_funcs)); + + return m; +} + +#endif + \ No newline at end of file diff --git a/src/quickjs.c b/src/quickjs.c index 715079e..f1b474f 100644 --- a/src/quickjs.c +++ b/src/quickjs.c @@ -4,6 +4,7 @@ #include #include "common.h" +#include "bindings/js_raylib_core.h" static JSContext *JS_NewCustomContext(JSRuntime *rt); static int eval_buf(JSContext *ctx, const void *buf, int buf_len, @@ -85,74 +86,12 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt) return NULL; /* system modules */ - js_init_module_std(ctx, "std"); - js_init_module_os(ctx, "os"); + //js_init_module_std(ctx, "std"); + //js_init_module_os(ctx, "os"); js_init_module_raylib_core(ctx, "raylib.core"); return ctx; } -static const JSCFunctionListEntry js_raylib_core_funcs[] = { - JS_FUNC_DEF("beginDrawing", 0, js_raylib_core_beginDrawing); - // JS_CFUNC_DEF("exit", 1, js_std_exit ), - // JS_CFUNC_DEF("gc", 0, js_std_gc ), - // JS_CFUNC_DEF("evalScript", 1, js_evalScript ), - // JS_CFUNC_DEF("loadScript", 1, js_loadScript ), - // JS_CFUNC_DEF("getenv", 1, js_std_getenv ), - // JS_CFUNC_DEF("setenv", 1, js_std_setenv ), - // JS_CFUNC_DEF("unsetenv", 1, js_std_unsetenv ), - // JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ), - // JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ), - // JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ), - // JS_CFUNC_DEF("strerror", 1, js_std_strerror ), - // JS_CFUNC_DEF("parseExtJSON", 1, js_std_parseExtJSON ), - - // /* FILE I/O */ - // JS_CFUNC_DEF("open", 2, js_std_open ), - // JS_CFUNC_DEF("popen", 2, js_std_popen ), - // JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ), - // JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ), - // JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ), - // JS_CFUNC_DEF("printf", 1, js_std_printf ), - // JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ), - // JS_PROP_INT32_DEF("SEEK_SET", SEEK_SET, JS_PROP_CONFIGURABLE ), - // JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ), - // JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ), - // JS_OBJECT_DEF("Error", js_std_error_props, countof(js_std_error_props), JS_PROP_CONFIGURABLE), -}; - -static int js_raylib_core_init(JSContext *ctx, JSModuleDef *m) -{ - JSValue proto; - - // /* FILE class */ - // /* the class ID is created once */ - // JS_NewClassID(&js_std_file_class_id); - // /* the class is created once per runtime */ - // JS_NewClass(JS_GetRuntime(ctx), js_std_file_class_id, &js_std_file_class); - // proto = JS_NewObject(ctx); - // JS_SetPropertyFunctionList(ctx, proto, js_std_file_proto_funcs, - // countof(js_std_file_proto_funcs)); - // JS_SetClassProto(ctx, js_std_file_class_id, proto); - - JS_SetModuleExportList(ctx, m, js_raylib_core_funcs, - countof(js_raylib_core_funcs)); - - // JS_SetModuleExport(ctx, m, "in", js_new_std_file(ctx, stdin, FALSE, FALSE)); - // JS_SetModuleExport(ctx, m, "out", js_new_std_file(ctx, stdout, FALSE, FALSE)); - // JS_SetModuleExport(ctx, m, "err", js_new_std_file(ctx, stderr, FALSE, FALSE)); - return 0; -} - -JSModuleDef *js_init_module_raylib_core(JSContext *ctx, const char *module_name) -{ - JSModuleDef *m; - m = JS_NewCModule(ctx, module_name, js_raylib_core_init); - if (!m) - return NULL; - - return m; -} - static int eval_buf(JSContext *ctx, const void *buf, int buf_len, const char *filename, int eval_flags) {