Extend binding generation

This commit is contained in:
Alexander Klingenbeck (SHS DI SY R&D DEV4) 2023-05-05 16:49:33 +02:00
parent 70e23cb149
commit c732761ae3
5 changed files with 85 additions and 15 deletions

View File

@ -2,8 +2,10 @@
{
"name": "raylib_core",
"functions": [
{ "name": "SetWindowTitle", "jsName": "setWindowTitle" },
{ "name": "SetWindowPosition", "jsName": "setWindowPosition" }
{ "name": "SetWindowTitle" },
{ "name": "SetWindowPosition" },
{ "name": "BeginDrawing" },
{ "name": "EndDrawing" }
]
}
]

View File

@ -46,32 +46,76 @@ const generateFunction = (functionList) => (func) => {
return cfunc.generate()
}
const generateParameterCheck = (func) => (param, i) => {
const errMsg = `${func.name} argument ${param.name} (${i}) needs to be`
switch(param.type){
case "const char *":
return `if(!JS_IsString(argv[${i}])) return JS_ThrowReferenceError(ctx, "${errMsg} a string");`
case "int":
return `if(!JS_IsNumber(argv[${i}])) return JS_ThrowReferenceError(ctx, "${errMsg} a number");`
default:
throw new Error("Unknown parameter type: "+param.type)
}
}
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}]);`
return `${param.type} ${param.name}; JS_ToInt32(ctx, &${param.name}, argv[${i}]);`
default:
throw new Error("Unknown parameter type: "+param.type)
}
}
const generateParameterCleanup = (param,i) => {
switch(param.type){
case "const char *":
return `JS_FreeCString(ctx, ${param.name});`
default:
return ""
}
}
class CFunction {
constructor(func, api, functionList){
this.func = func
this.func.jsName = this.func.jsName || this.func.name.charAt(0).toLowerCase() + this.func.name.slice(1);
this.api = api
this.api.params = this.api.params || [];
this.functionList = functionList
this.functionName = `js_${func.jsName}`
}
generateParameterCheck(){
return this.api.params.map(generateParameterCheck(this.api))
}
generateParameters(){
return this.api.params.map(generateParameter)
}
generateFunctionCall(){
return `${(this.api.returnType === 'void' ? '' : `${this.api.returnType} result = `)}${this.api.name}(${this.api.params.map(x => x.name).join(", ")});`
}
generateReturn(){
return this.api.returnType === 'void' ? 'return JS_UNDEFINED;' : 'return result'
}
generateParametersCleanup(){
return this.api.params.map(generateParameterCleanup).filter(x => x !== "")
}
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;
${this.generateParameterCheck().join("\n ")}
${this.generateParameters().join("\n ")}
${this.generateFunctionCall()}
${this.generateParametersCleanup().join("\n ")}
${this.generateReturn()}
}`
}
}

View File

@ -1,5 +1,6 @@
import { setWindowTitle } from "raylib.core"
import { setWindowTitle, setWindowPosition } from "raylib.core"
console.log(setWindowTitle("Test"))
setWindowTitle("My Window")
setWindowPosition(50,50)

View File

@ -13,21 +13,44 @@
#endif
static JSValue js_setWindowTitle(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){
const char * title = JS_ToCString(ctx, argv[0]);
if(!JS_IsString(argv[0])) return JS_ThrowReferenceError(ctx, "SetWindowTitle argument title (0) needs to be a string");
const char * title = JS_ToCString(ctx, argv[0]);
SetWindowTitle(title);
JS_FreeCString(ctx, title);
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]);
if(!JS_IsNumber(argv[0])) return JS_ThrowReferenceError(ctx, "SetWindowPosition argument x (0) needs to be a number");
if(!JS_IsNumber(argv[1])) return JS_ThrowReferenceError(ctx, "SetWindowPosition argument y (1) needs to be a number");
int x; JS_ToInt32(ctx, &x, argv[0]);
int y; JS_ToInt32(ctx, &y, argv[1]);
SetWindowPosition(x, y);
return JS_UNDEFINED;
}
static JSValue js_beginDrawing(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){
BeginDrawing();
return JS_UNDEFINED;
}
static JSValue js_endDrawing(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv){
EndDrawing();
return JS_UNDEFINED;
}
static const JSCFunctionListEntry js_raylib_core_funcs[] = {
JS_CFUNC_DEF("setWindowTitle", 1, js_setWindowTitle),
JS_CFUNC_DEF("setWindowPosition", 2, js_setWindowPosition)
JS_CFUNC_DEF("setWindowPosition", 2, js_setWindowPosition),
JS_CFUNC_DEF("beginDrawing", 0, js_beginDrawing),
JS_CFUNC_DEF("endDrawing", 0, js_endDrawing)
};
static int js_raylib_core_init(JSContext *ctx, JSModuleDef *m){

View File

@ -71,7 +71,7 @@ int app_update_quickjs(){
}
int app_dispose_quickjs(){
js_std_free_handlers(rt);
//js_std_free_handlers(rt);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
@ -86,7 +86,7 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
return NULL;
/* system modules */
//js_init_module_std(ctx, "std");
js_init_module_std(ctx, "std");
//js_init_module_os(ctx, "os");
js_init_module_raylib_core(ctx, "raylib.core");
return ctx;