mirror of https://github.com/mode777/rayjs.git
				
				
				
			more bindings
This commit is contained in:
		
							parent
							
								
									b48568aa87
								
							
						
					
					
						commit
						277a85f527
					
				|  | @ -1,17 +0,0 @@ | |||
| { | ||||
|     "headers": [ | ||||
|         { | ||||
|             "name": "raylib_core", | ||||
|             "functions": [ | ||||
|                 { "name": "SetWindowTitle" }, | ||||
|                 { "name": "SetWindowPosition" }, | ||||
|                 { "name": "BeginDrawing" }, | ||||
|                 { "name": "EndDrawing" } | ||||
|             ]         | ||||
|         }, | ||||
|         { | ||||
|             "name": "raylib_texture", | ||||
|             "functions": [] | ||||
|         } | ||||
|     ] | ||||
| } | ||||
|  | @ -214,6 +214,11 @@ export abstract class GenericCodeGenerator<T extends CodeGenerator> { | |||
|         if(fun) fun(sub) | ||||
|         return sub | ||||
|     }     | ||||
| 
 | ||||
|     public declareStruct(structName: string, varName: string, values: string[], isStatic: boolean = false){ | ||||
|         if(isStatic) this.inline("static ") | ||||
|         this.statement(`${structName} ${varName} = { ${values.join(', ')} }`) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class CodeGenerator extends GenericCodeGenerator<CodeGenerator>{ | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { readFileSync, writeFileSync } from "fs"; | ||||
| import { Bindings, RayLibApi } from "./interfaces"; | ||||
| import { RayLibApi } from "./interfaces"; | ||||
| import { ApiDescription } from "./api"; | ||||
| import { RayLibHeader } from "./raylib-header"; | ||||
| 
 | ||||
|  | @ -17,12 +17,28 @@ function main(){ | |||
|         }, | ||||
|         createConstructor: true | ||||
|     }) | ||||
|     core_gen.addApiStructByName("Vector2", { | ||||
|         properties: { | ||||
|             x: { get: true, set: true }, | ||||
|             y: { get: true, set: true }, | ||||
|         }, | ||||
|         createConstructor: true | ||||
|     }) | ||||
|     core_gen.addApiFunctionByName("SetWindowTitle") | ||||
|     core_gen.addApiFunctionByName("SetWindowPosition") | ||||
|     core_gen.addApiFunctionByName("BeginDrawing") | ||||
|     core_gen.addApiFunctionByName("EndDrawing") | ||||
|     core_gen.addApiFunctionByName("InitWindow") | ||||
|     core_gen.addApiFunctionByName("SetTargetFPS") | ||||
|     core_gen.addApiFunctionByName("WindowShouldClose", null, { before: fun => fun.call("app_update_quickjs", []) }) | ||||
|     core_gen.addApiFunctionByName("ClearBackground") | ||||
|     core_gen.addApiFunctionByName("CloseWindow") | ||||
|     core_gen.addApiFunctionByName("DrawText") | ||||
|     core_gen.addApiFunctionByName("DrawCircleV") | ||||
|     core_gen.addApiFunctionByName("IsKeyDown") | ||||
|     api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { | ||||
|         core_gen.exportGlobalStruct("Color", x.name, x.values) | ||||
|     }) | ||||
|     core_gen.writeTo("src/bindings/js_raylib_core.h") | ||||
| 
 | ||||
|     const texture_gen = new RayLibHeader("raylib_texture", apiDesc) | ||||
|  |  | |||
|  | @ -48,17 +48,4 @@ export interface RayLibApi { | |||
|     structs: RayLibStruct[], | ||||
|     enums: RayLibEnum[], | ||||
|     functions: RayLibFunction[] | ||||
| } | ||||
| 
 | ||||
| export interface BindingFunction { | ||||
|     name: string | ||||
| } | ||||
| 
 | ||||
| export interface BindingHeader { | ||||
|     name: string, | ||||
|     functions: BindingFunction[], | ||||
| } | ||||
| 
 | ||||
| export interface Bindings { | ||||
|     headers: BindingHeader | ||||
| } | ||||
|  | @ -76,12 +76,17 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend | |||
|         return sub      | ||||
|     } | ||||
|      | ||||
|     jsToC(type: string, name: string, src: string){ | ||||
|     jsToC(type: string, name: string, src: string, classIds: StructLookup = {}){ | ||||
|         switch (type) { | ||||
|             case "const char *": | ||||
|                 this.statement(`${type} ${name} = JS_ToCString(ctx, ${src})`) | ||||
|                 this.statement(`if(${name} == NULL) return JS_EXCEPTION`) | ||||
|                 break; | ||||
|             case "float": | ||||
|                 this.statement("double _double_"+name) | ||||
|                 this.statement(`JS_ToFloat64(ctx, &_double_${name}, ${src})`) | ||||
|                 this.statement(`${type} ${name} = (${type})_double_${name}`) | ||||
|                 break; | ||||
|             case "int": | ||||
|                 this.statement(`${type} ${name}`) | ||||
|                 this.statement(`JS_ToInt32(ctx, &${name}, ${src})`) | ||||
|  | @ -92,7 +97,11 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend | |||
|                 this.statement(`${type} ${name} = (${type})_int_${name}`) | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new Error("Cannot handle parameter type: " + type) | ||||
|                 const classId = classIds[type] | ||||
|                 if(!classId) throw new Error("Cannot convert into parameter type: " + type) | ||||
|                 this.jsOpqToStructPtr(type, name+"_ptr", src, classId) | ||||
|                 this.statement(`if(${name}_ptr == NULL) return JS_EXCEPTION`) | ||||
|                 this.declare(name, type, false, `*${name}_ptr`) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -102,18 +111,24 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend | |||
|             case "unsigned char": | ||||
|                 this.declare(name,'JSValue', false, `JS_NewInt32(ctx, ${src})`) | ||||
|                 break; | ||||
|             case "bool": | ||||
|                 this.declare(name, 'JSValue', false, `JS_NewBool(ctx, ${src})`) | ||||
|                 break; | ||||
|             case "float": | ||||
|                 this.declare(name, 'JSValue', false, `JS_NewFloat64(ctx, ${src})`) | ||||
|                 break; | ||||
|             default: | ||||
|                 const classId = classIds[type] | ||||
|                 if(!classId) throw new Error("Cannot handle parameter type: " + type) | ||||
|                 if(!classId) throw new Error("Cannot convert parameter type to Javascript: " + type) | ||||
|                 this.jsStructToOpq(type, name, src, classId) | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     jsStructToOpq(structType: string, jsVar: string, srcVar: string, classId: string){ | ||||
|         this.declare("ptr", structType+"*", false, `(${structType}*)js_malloc(ctx, sizeof(${structType}))`) | ||||
|         this.statement("*ptr = " + srcVar) | ||||
|         this.declare(jsVar+"_ptr", structType+"*", false, `(${structType}*)js_malloc(ctx, sizeof(${structType}))`) | ||||
|         this.statement("*"+jsVar+"_ptr = " + srcVar) | ||||
|         this.declare(jsVar, "JSValue", false, `JS_NewObjectClass(ctx, ${classId})`) | ||||
|         this.call("JS_SetOpaque", [jsVar, "ptr"]) | ||||
|         this.call("JS_SetOpaque", [jsVar, jsVar+"_ptr"]) | ||||
|     } | ||||
| 
 | ||||
|     jsCleanUpParameter(type: string, name: string) { | ||||
|  | @ -207,13 +222,17 @@ export abstract class GenericQuickJsGenerator<T extends QuickJsGenerator> extend | |||
|         return fun | ||||
|     } | ||||
| 
 | ||||
|     jsOpqToStructPtr(structType: string, structVar: string, srcVar: string, classId: string){ | ||||
|         this.declare(structVar, structType+"*", false, `(${structType}*)JS_GetOpaque2(ctx, ${srcVar}, ${classId})`) | ||||
|     } | ||||
| 
 | ||||
|     jsStructConstructor(structName: string, fields: FunctionArgument[], classId: string){ | ||||
|         const body = this.jsBindingFunction(structName + "_constructor") | ||||
|         for (let i = 0; i < fields.length; i++) { | ||||
|             const para = fields[i] | ||||
|             body.jsToC(para.type,para.name,"argv["+i+"]") | ||||
|         } | ||||
|         body.statement(`${structName} _struct = { ${fields.map(x => x.name).join(', ')} }`) | ||||
|         body.declareStruct(structName, "_struct", fields.map(x => x.name)) | ||||
|         body.jsStructToOpq(structName,"_return","_struct", classId) | ||||
|         body.returnExp("_return") | ||||
|         return body | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { ApiDescription, ApiFunction, ApiStruct } from "./api" | ||||
| import { CodeGenerator } from "./generation" | ||||
| import { QuickJsHeader } from "./quickjs" | ||||
| import { QuickJsGenerator, QuickJsHeader } from "./quickjs" | ||||
| 
 | ||||
| export interface StructBindingOptions { | ||||
|     properties?: { [key:string]: { get?:boolean, set?:boolean } }, | ||||
|  | @ -9,6 +9,11 @@ export interface StructBindingOptions { | |||
|     createConstructor?: boolean | ||||
| } | ||||
| 
 | ||||
| export interface FuncBindingOptions { | ||||
|     before?: (gen: QuickJsGenerator) => void | ||||
|     after?: (gen: QuickJsGenerator) => void | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| export class RayLibHeader extends QuickJsHeader { | ||||
| 
 | ||||
|  | @ -17,14 +22,15 @@ export class RayLibHeader extends QuickJsHeader { | |||
|         this.includes.include("raylib.h") | ||||
|     } | ||||
| 
 | ||||
|     addApiFunction(api: ApiFunction, jsName: string | null = null){ | ||||
|     addApiFunction(api: ApiFunction, jsName: string | null = null, options: FuncBindingOptions = {}){ | ||||
|         const jName = jsName || api.name.charAt(0).toLowerCase() + api.name.slice(1) | ||||
| 
 | ||||
|         const fun = this.functions.jsBindingFunction(jName) | ||||
|         if(options.before) options.before(fun) | ||||
|         // read parameters
 | ||||
|         for (let i = 0; i < api.params.length; i++) { | ||||
|             const para = api.params[i] | ||||
|             fun.jsToC(para.type,para.name,"argv["+i+"]") | ||||
|             fun.jsToC(para.type,para.name,"argv["+i+"]", this.structLookup) | ||||
|         } | ||||
|         // call c function
 | ||||
|         fun.call(api.name, api.params.map(x => x.name), api.returnType === "void" ? null : {type: api.returnType, name: "returnVal"}) | ||||
|  | @ -32,6 +38,7 @@ export class RayLibHeader extends QuickJsHeader { | |||
|         for (const param of api.params) { | ||||
|             fun.jsCleanUpParameter(param.type, param.name) | ||||
|         } | ||||
|         if(options.after) options.after(fun) | ||||
|         // return result
 | ||||
|         if(api.returnType === "void"){ | ||||
|             fun.statement("return JS_UNDEFINED") | ||||
|  | @ -44,10 +51,10 @@ export class RayLibHeader extends QuickJsHeader { | |||
|         this.moduleFunctionList.jsFuncDef(jName, api.argc, fun.getTag("_name")) | ||||
|     } | ||||
| 
 | ||||
|     addApiFunctionByName(name: string, jsName: string | null = null){ | ||||
|     addApiFunctionByName(name: string, jsName: string | null = null, options: FuncBindingOptions = {}){ | ||||
|         const func = this.api.getFunction(name) | ||||
|         if(func === null) throw new Error("Function not in API: " + name) | ||||
|         this.addApiFunction(func, jsName) | ||||
|         this.addApiFunction(func, jsName, options) | ||||
|     } | ||||
| 
 | ||||
|     addApiStruct(struct: ApiStruct, destructor: ApiFunction | null, options?: StructBindingOptions){ | ||||
|  | @ -86,6 +93,15 @@ export class RayLibHeader extends QuickJsHeader { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     exportGlobalStruct(structName: string, exportName: string, values: string[]){ | ||||
|         this.moduleInit.declareStruct(structName,exportName+"_struct", values) | ||||
|         const classId = this.structLookup[structName] | ||||
|         if(!classId) throw new Error("Struct "+structName+" not found in register") | ||||
|         this.moduleInit.jsStructToOpq(structName, exportName+"_js", exportName+"_struct", classId) | ||||
|         this.moduleInit.call("JS_SetModuleExport", ["ctx","m",`"${exportName}"`, exportName+"_js"]) | ||||
|         this.moduleEntry.call("JS_AddModuleExport", ["ctx","m",`"${exportName}"`]) | ||||
|     } | ||||
| 
 | ||||
|     addApiStructByName(structName: string, options?: StructBindingOptions){ | ||||
|         const struct = this.api.getStruct(structName) | ||||
|         if(!struct) throw new Error("Struct not in API: "+ structName) | ||||
|  |  | |||
|  | @ -0,0 +1,33 @@ | |||
| import * as rlc from "raylib.core" | ||||
| 
 | ||||
| // Initialization
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| const screenWidth = 800; | ||||
| const screenHeight = 450; | ||||
| 
 | ||||
| rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); | ||||
| 
 | ||||
| rlc.setTargetFPS(60);               // Set our game to run at 60 frames-per-second
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| 
 | ||||
| // Main game loop
 | ||||
| while (!rlc.windowShouldClose())    // Detect window close button or ESC key
 | ||||
| { | ||||
|     // Update
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     // TODO: Update your variables here
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     // Draw
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     rlc.beginDrawing(); | ||||
| 
 | ||||
|         rlc.clearBackground(rlc.RAYWHITE); | ||||
| 
 | ||||
|         rlc.drawText("Congrats! You created your first window!", 190, 200, 20, rlc.LIGHTGRAY); | ||||
| 
 | ||||
|     rlc.endDrawing(); | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| } | ||||
| 
 | ||||
|  | @ -0,0 +1,48 @@ | |||
| import * as rlc from "raylib.core" | ||||
| 
 | ||||
| const KEY_RIGHT           = 262      // Key: Cursor right
 | ||||
| const KEY_LEFT            = 263      // Key: Cursor left
 | ||||
| const KEY_DOWN            = 264      // Key: Cursor down
 | ||||
| const KEY_UP              = 265      // Key: Cursor up
 | ||||
| 
 | ||||
| // Initialization
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| const screenWidth = 800; | ||||
| const screenHeight = 450; | ||||
| 
 | ||||
| rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - keyboard input"); | ||||
| 
 | ||||
| const ballPosition = new rlc.Vector2(screenWidth/2, screenHeight/2); | ||||
| 
 | ||||
| rlc.setTargetFPS(60);               // Set our game to run at 60 frames-per-second
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| // Main game loop
 | ||||
| while (!rlc.windowShouldClose())    // Detect window close button or ESC key
 | ||||
| { | ||||
|     // Update
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     if (rlc.isKeyDown(KEY_RIGHT)) ballPosition.x += 2; | ||||
|     if (rlc.isKeyDown(KEY_LEFT)) ballPosition.x -= 2; | ||||
|     if (rlc.isKeyDown(KEY_UP)) ballPosition.y -= 2; | ||||
|     if (rlc.isKeyDown(KEY_DOWN)) ballPosition.y += 2; | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     // Draw
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     rlc.beginDrawing(); | ||||
| 
 | ||||
|         rlc.clearBackground(rlc.RAYWHITE); | ||||
| 
 | ||||
|         rlc.drawText("move the ball with arrow keys", 10, 10, 20, rlc.DARKGRAY); | ||||
| 
 | ||||
|         rlc.drawCircleV(ballPosition, 50, rlc.MAROON); | ||||
| 
 | ||||
|     rlc.endDrawing(); | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| } | ||||
| 
 | ||||
| // De-Initialization
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| rlc.closeWindow();        // Close window and OpenGL context
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
|  | @ -258,6 +258,11 @@ class GenericCodeGenerator { | |||
|             fun(sub); | ||||
|         return sub; | ||||
|     } | ||||
|     declareStruct(structName, varName, values, isStatic = false) { | ||||
|         if (isStatic) | ||||
|             this.inline("static "); | ||||
|         this.statement(`${structName} ${varName} = { ${values.join(', ')} }`); | ||||
|     } | ||||
| } | ||||
| exports.GenericCodeGenerator = GenericCodeGenerator; | ||||
| class CodeGenerator extends GenericCodeGenerator { | ||||
|  | @ -336,12 +341,17 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { | |||
|         const sub = this.function("js_" + jsName, "JSValue", args, true); | ||||
|         return sub; | ||||
|     } | ||||
|     jsToC(type, name, src) { | ||||
|     jsToC(type, name, src, classIds = {}) { | ||||
|         switch (type) { | ||||
|             case "const char *": | ||||
|                 this.statement(`${type} ${name} = JS_ToCString(ctx, ${src})`); | ||||
|                 this.statement(`if(${name} == NULL) return JS_EXCEPTION`); | ||||
|                 break; | ||||
|             case "float": | ||||
|                 this.statement("double _double_" + name); | ||||
|                 this.statement(`JS_ToFloat64(ctx, &_double_${name}, ${src})`); | ||||
|                 this.statement(`${type} ${name} = (${type})_double_${name}`); | ||||
|                 break; | ||||
|             case "int": | ||||
|                 this.statement(`${type} ${name}`); | ||||
|                 this.statement(`JS_ToInt32(ctx, &${name}, ${src})`); | ||||
|  | @ -352,7 +362,12 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { | |||
|                 this.statement(`${type} ${name} = (${type})_int_${name}`); | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new Error("Cannot handle parameter type: " + type); | ||||
|                 const classId = classIds[type]; | ||||
|                 if (!classId) | ||||
|                     throw new Error("Cannot convert into parameter type: " + type); | ||||
|                 this.jsOpqToStructPtr(type, name + "_ptr", src, classId); | ||||
|                 this.statement(`if(${name}_ptr == NULL) return JS_EXCEPTION`); | ||||
|                 this.declare(name, type, false, `*${name}_ptr`); | ||||
|         } | ||||
|     } | ||||
|     jsToJs(type, name, src, classIds = {}) { | ||||
|  | @ -361,18 +376,24 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { | |||
|             case "unsigned char": | ||||
|                 this.declare(name, 'JSValue', false, `JS_NewInt32(ctx, ${src})`); | ||||
|                 break; | ||||
|             case "bool": | ||||
|                 this.declare(name, 'JSValue', false, `JS_NewBool(ctx, ${src})`); | ||||
|                 break; | ||||
|             case "float": | ||||
|                 this.declare(name, 'JSValue', false, `JS_NewFloat64(ctx, ${src})`); | ||||
|                 break; | ||||
|             default: | ||||
|                 const classId = classIds[type]; | ||||
|                 if (!classId) | ||||
|                     throw new Error("Cannot handle parameter type: " + type); | ||||
|                     throw new Error("Cannot convert parameter type to Javascript: " + type); | ||||
|                 this.jsStructToOpq(type, name, src, classId); | ||||
|         } | ||||
|     } | ||||
|     jsStructToOpq(structType, jsVar, srcVar, classId) { | ||||
|         this.declare("ptr", structType + "*", false, `(${structType}*)js_malloc(ctx, sizeof(${structType}))`); | ||||
|         this.statement("*ptr = " + srcVar); | ||||
|         this.declare(jsVar + "_ptr", structType + "*", false, `(${structType}*)js_malloc(ctx, sizeof(${structType}))`); | ||||
|         this.statement("*" + jsVar + "_ptr = " + srcVar); | ||||
|         this.declare(jsVar, "JSValue", false, `JS_NewObjectClass(ctx, ${classId})`); | ||||
|         this.call("JS_SetOpaque", [jsVar, "ptr"]); | ||||
|         this.call("JS_SetOpaque", [jsVar, jsVar + "_ptr"]); | ||||
|     } | ||||
|     jsCleanUpParameter(type, name) { | ||||
|         switch (type) { | ||||
|  | @ -456,13 +477,16 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { | |||
|         fun.returnExp("JS_UNDEFINED"); | ||||
|         return fun; | ||||
|     } | ||||
|     jsOpqToStructPtr(structType, structVar, srcVar, classId) { | ||||
|         this.declare(structVar, structType + "*", false, `(${structType}*)JS_GetOpaque2(ctx, ${srcVar}, ${classId})`); | ||||
|     } | ||||
|     jsStructConstructor(structName, fields, classId) { | ||||
|         const body = this.jsBindingFunction(structName + "_constructor"); | ||||
|         for (let i = 0; i < fields.length; i++) { | ||||
|             const para = fields[i]; | ||||
|             body.jsToC(para.type, para.name, "argv[" + i + "]"); | ||||
|         } | ||||
|         body.statement(`${structName} _struct = { ${fields.map(x => x.name).join(', ')} }`); | ||||
|         body.declareStruct(structName, "_struct", fields.map(x => x.name)); | ||||
|         body.jsStructToOpq(structName, "_return", "_struct", classId); | ||||
|         body.returnExp("_return"); | ||||
|         return body; | ||||
|  | @ -495,13 +519,15 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { | |||
|         this.api = api; | ||||
|         this.includes.include("raylib.h"); | ||||
|     } | ||||
|     addApiFunction(api, jsName = null) { | ||||
|     addApiFunction(api, jsName = null, options = {}) { | ||||
|         const jName = jsName || api.name.charAt(0).toLowerCase() + api.name.slice(1); | ||||
|         const fun = this.functions.jsBindingFunction(jName); | ||||
|         if (options.before) | ||||
|             options.before(fun); | ||||
|         // read parameters
 | ||||
|         for (let i = 0; i < api.params.length; i++) { | ||||
|             const para = api.params[i]; | ||||
|             fun.jsToC(para.type, para.name, "argv[" + i + "]"); | ||||
|             fun.jsToC(para.type, para.name, "argv[" + i + "]", this.structLookup); | ||||
|         } | ||||
|         // call c function
 | ||||
|         fun.call(api.name, api.params.map(x => x.name), api.returnType === "void" ? null : { type: api.returnType, name: "returnVal" }); | ||||
|  | @ -509,6 +535,8 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { | |||
|         for (const param of api.params) { | ||||
|             fun.jsCleanUpParameter(param.type, param.name); | ||||
|         } | ||||
|         if (options.after) | ||||
|             options.after(fun); | ||||
|         // return result
 | ||||
|         if (api.returnType === "void") { | ||||
|             fun.statement("return JS_UNDEFINED"); | ||||
|  | @ -520,11 +548,11 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { | |||
|         // add binding to function declaration
 | ||||
|         this.moduleFunctionList.jsFuncDef(jName, api.argc, fun.getTag("_name")); | ||||
|     } | ||||
|     addApiFunctionByName(name, jsName = null) { | ||||
|     addApiFunctionByName(name, jsName = null, options = {}) { | ||||
|         const func = this.api.getFunction(name); | ||||
|         if (func === null) | ||||
|             throw new Error("Function not in API: " + name); | ||||
|         this.addApiFunction(func, jsName); | ||||
|         this.addApiFunction(func, jsName, options); | ||||
|     } | ||||
|     addApiStruct(struct, destructor, options) { | ||||
|         const classId = this.declarations.jsClassId(`js_${struct.name}_class_id`); | ||||
|  | @ -558,6 +586,15 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { | |||
|             this.moduleEntry.call("JS_AddModuleExport", ["ctx", "m", '"' + struct.name + '"']); | ||||
|         } | ||||
|     } | ||||
|     exportGlobalStruct(structName, exportName, values) { | ||||
|         this.moduleInit.declareStruct(structName, exportName + "_struct", values); | ||||
|         const classId = this.structLookup[structName]; | ||||
|         if (!classId) | ||||
|             throw new Error("Struct " + structName + " not found in register"); | ||||
|         this.moduleInit.jsStructToOpq(structName, exportName + "_js", exportName + "_struct", classId); | ||||
|         this.moduleInit.call("JS_SetModuleExport", ["ctx", "m", `"${exportName}"`, exportName + "_js"]); | ||||
|         this.moduleEntry.call("JS_AddModuleExport", ["ctx", "m", `"${exportName}"`]); | ||||
|     } | ||||
|     addApiStructByName(structName, options) { | ||||
|         const struct = this.api.getStruct(structName); | ||||
|         if (!struct) | ||||
|  | @ -638,12 +675,28 @@ function main() { | |||
|         }, | ||||
|         createConstructor: true | ||||
|     }); | ||||
|     core_gen.addApiStructByName("Vector2", { | ||||
|         properties: { | ||||
|             x: { get: true, set: true }, | ||||
|             y: { get: true, set: true }, | ||||
|         }, | ||||
|         createConstructor: true | ||||
|     }); | ||||
|     core_gen.addApiFunctionByName("SetWindowTitle"); | ||||
|     core_gen.addApiFunctionByName("SetWindowPosition"); | ||||
|     core_gen.addApiFunctionByName("BeginDrawing"); | ||||
|     core_gen.addApiFunctionByName("EndDrawing"); | ||||
|     core_gen.addApiFunctionByName("InitWindow"); | ||||
|     core_gen.addApiFunctionByName("SetTargetFPS"); | ||||
|     core_gen.addApiFunctionByName("WindowShouldClose", null, { before: fun => fun.call("app_update_quickjs", []) }); | ||||
|     core_gen.addApiFunctionByName("ClearBackground"); | ||||
|     core_gen.addApiFunctionByName("CloseWindow"); | ||||
|     core_gen.addApiFunctionByName("DrawText"); | ||||
|     core_gen.addApiFunctionByName("DrawCircleV"); | ||||
|     core_gen.addApiFunctionByName("IsKeyDown"); | ||||
|     api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { | ||||
|         core_gen.exportGlobalStruct("Color", x.name, x.values); | ||||
|     }); | ||||
|     core_gen.writeTo("src/bindings/js_raylib_core.h"); | ||||
|     const texture_gen = new raylib_header_1.RayLibHeader("raylib_texture", apiDesc); | ||||
|     texture_gen.addApiStructByName("Image", { | ||||
|  |  | |||
|  | @ -1,191 +0,0 @@ | |||
| // Run with Node.js
 | ||||
| 
 | ||||
| const fs = require('fs'); | ||||
| const { connect } = require('http2'); | ||||
| let api, modules | ||||
| 
 | ||||
| async function main(){ | ||||
|   api = await readJson('thirdparty/raylib/parser/output/raylib_api.json') | ||||
|   modules = await readJson('bindings.json') | ||||
|    | ||||
|   const headers = modules.map(generateModule) | ||||
| 
 | ||||
|   modules.forEach(async (header,i) => { | ||||
|     await writeFile(`src/bindings/js_${header.name}.h`, headers[i]) | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class FunctionList { | ||||
|   definitions = [] | ||||
| 
 | ||||
|   addFunctionDef(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 = (functionList) => (func) => { | ||||
|   const api = findFunction(func.name) | ||||
|   const cfunc = new CFunction(func, api, functionList) | ||||
|   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}; 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.generateParameterCheck().join("\n    ")}     | ||||
|     ${this.generateParameters().join("\n    ")}     | ||||
|     ${this.generateFunctionCall()}     | ||||
|     ${this.generateParametersCleanup().join("\n    ")}         | ||||
|     ${this.generateReturn()} | ||||
| }` | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 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() | ||||
|     }) | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| function generateHeader(name, content){ | ||||
|   return ` | ||||
| #ifndef JS_${name} | ||||
| #define JS_${name} | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include <quickjs.h> | ||||
| 
 | ||||
| #ifndef countof | ||||
| #define countof(x) (sizeof(x) / sizeof((x)[0])) | ||||
| #endif | ||||
| 
 | ||||
| ${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; | ||||
| 
 | ||||
|     JS_AddModuleExportList(ctx, m, js_${name}_funcs, | ||||
|       countof(js_${name}_funcs)); | ||||
| 
 | ||||
|     return m; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|   ` | ||||
| } | ||||
| 
 | ||||
| main() | ||||
							
								
								
									
										40
									
								
								main.js
								
								
								
								
							
							
						
						
									
										40
									
								
								main.js
								
								
								
								
							|  | @ -1,19 +1,35 @@ | |||
| import { setWindowTitle, setWindowPosition, Color } from "raylib.core" | ||||
| import * as rlc from "raylib.core" | ||||
| import { loadImage } from "raylib.texture" | ||||
| import { gc } from "std" | ||||
| 
 | ||||
| const img = loadImage("assets/planet00.png") | ||||
| console.log(img.width) | ||||
| // Initialization
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| const screenWidth = 800; | ||||
| const screenHeight = 450; | ||||
| 
 | ||||
| //const img = new Image("assets/planet00.png")
 | ||||
| rlc.initWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); | ||||
| 
 | ||||
| gc() | ||||
| 
 | ||||
| const color = new Color(1,2,3,4) | ||||
| color.r = 10 | ||||
| console.log(color.r,color.g,color.b,color.a, color) | ||||
| 
 | ||||
| setWindowTitle("My Window") | ||||
| setWindowPosition(20,50) | ||||
| rlc.setTargetFPS(60);               // Set our game to run at 60 frames-per-second
 | ||||
| //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| 
 | ||||
| // Main game loop
 | ||||
| while (!rlc.windowShouldClose())    // Detect window close button or ESC key
 | ||||
| { | ||||
|     // Update
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     // TODO: Update your variables here
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     // Draw
 | ||||
|     //----------------------------------------------------------------------------------
 | ||||
|     rlc.beginDrawing(); | ||||
| 
 | ||||
|         rlc.clearBackground(rlc.RAYWHITE); | ||||
| 
 | ||||
|         rlc.drawText("Congrats! You created your first window!", 190, 200, 20, rlc.LIGHTGRAY); | ||||
| 
 | ||||
|     rlc.endDrawing(); | ||||
|     //----------------------------------------------------------------------------------
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +0,0 @@ | |||
| export function test() { | ||||
|     return 42 | ||||
| } | ||||
|  | @ -13,6 +13,7 @@ | |||
| #endif | ||||
| 
 | ||||
| static JSClassID js_Color_class_id; | ||||
| static JSClassID js_Vector2_class_id; | ||||
| 
 | ||||
| static void js_Color_finalizer(JSRuntime * rt, JSValue val) { | ||||
|     Color* ptr = JS_GetOpaque(val, js_Color_class_id); | ||||
|  | @ -128,6 +129,74 @@ static int js_declare_Color(JSContext * ctx, JSModuleDef * m) { | |||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void js_Vector2_finalizer(JSRuntime * rt, JSValue val) { | ||||
|     Vector2* ptr = JS_GetOpaque(val, js_Vector2_class_id); | ||||
|     if(ptr) { | ||||
|         TraceLog(LOG_INFO, "Finalize Vector2"); | ||||
|         js_free_rt(rt, ptr); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Vector2_get_x(JSContext* ctx, JSValueConst this_val) { | ||||
|     Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); | ||||
|     if(!ptr) { | ||||
|         return JS_EXCEPTION; | ||||
|     } | ||||
|     float x = ptr->x; | ||||
|     JSValue ret = JS_NewFloat64(ctx, x); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Vector2_set_x(JSContext* ctx, JSValueConst this_val, JSValueConst v) { | ||||
|     Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); | ||||
|     if(!ptr) { | ||||
|         return JS_EXCEPTION; | ||||
|     } | ||||
|     double _double_value; | ||||
|     JS_ToFloat64(ctx, &_double_value, v); | ||||
|     float value = (float)_double_value; | ||||
|     ptr->x = value; | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Vector2_get_y(JSContext* ctx, JSValueConst this_val) { | ||||
|     Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); | ||||
|     if(!ptr) { | ||||
|         return JS_EXCEPTION; | ||||
|     } | ||||
|     float y = ptr->y; | ||||
|     JSValue ret = JS_NewFloat64(ctx, y); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Vector2_set_y(JSContext* ctx, JSValueConst this_val, JSValueConst v) { | ||||
|     Vector2* ptr = JS_GetOpaque2(ctx, this_val, js_Vector2_class_id); | ||||
|     if(!ptr) { | ||||
|         return JS_EXCEPTION; | ||||
|     } | ||||
|     double _double_value; | ||||
|     JS_ToFloat64(ctx, &_double_value, v); | ||||
|     float value = (float)_double_value; | ||||
|     ptr->y = value; | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static const JSCFunctionListEntry js_Vector2_proto_funcs[] = { | ||||
|     JS_CGETSET_DEF("x",js_Vector2_get_x,js_Vector2_set_x), | ||||
|     JS_CGETSET_DEF("y",js_Vector2_get_y,js_Vector2_set_y), | ||||
|     JS_PROP_STRING_DEF("[Symbol.toStringTag]","Vector2", JS_PROP_CONFIGURABLE), | ||||
| }; | ||||
| 
 | ||||
| static int js_declare_Vector2(JSContext * ctx, JSModuleDef * m) { | ||||
|     JS_NewClassID(&js_Vector2_class_id); | ||||
|     JSClassDef js_Vector2_def = { .class_name = "Vector2", .finalizer = js_Vector2_finalizer }; | ||||
|     JS_NewClass(JS_GetRuntime(ctx), js_Vector2_class_id, &js_Vector2_def); | ||||
|     JSValue proto = JS_NewObject(ctx); | ||||
|     JS_SetPropertyFunctionList(ctx, proto, js_Vector2_proto_funcs, countof(js_Vector2_proto_funcs)); | ||||
|     JS_SetClassProto(ctx, js_Vector2_class_id, proto); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Color_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     int _int_r; | ||||
|     JS_ToInt32(ctx, &_int_r, argv[0]); | ||||
|  | @ -142,10 +211,25 @@ static JSValue js_Color_constructor(JSContext * ctx, JSValueConst this_val, int | |||
|     JS_ToInt32(ctx, &_int_a, argv[3]); | ||||
|     unsigned char a = (unsigned char)_int_a; | ||||
|     Color _struct = { r, g, b, a }; | ||||
|     Color* ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *ptr = _struct; | ||||
|     Color* _return_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *_return_ptr = _struct; | ||||
|     JSValue _return = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(_return, ptr); | ||||
|     JS_SetOpaque(_return, _return_ptr); | ||||
|     return _return; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_Vector2_constructor(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     double _double_x; | ||||
|     JS_ToFloat64(ctx, &_double_x, argv[0]); | ||||
|     float x = (float)_double_x; | ||||
|     double _double_y; | ||||
|     JS_ToFloat64(ctx, &_double_y, argv[1]); | ||||
|     float y = (float)_double_y; | ||||
|     Vector2 _struct = { x, y }; | ||||
|     Vector2* _return_ptr = (Vector2*)js_malloc(ctx, sizeof(Vector2)); | ||||
|     *_return_ptr = _struct; | ||||
|     JSValue _return = JS_NewObjectClass(ctx, js_Vector2_class_id); | ||||
|     JS_SetOpaque(_return, _return_ptr); | ||||
|     return _return; | ||||
| } | ||||
| 
 | ||||
|  | @ -176,11 +260,97 @@ static JSValue js_endDrawing(JSContext * ctx, JSValueConst this_val, int argc, J | |||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_initWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     int width; | ||||
|     JS_ToInt32(ctx, &width, argv[0]); | ||||
|     int height; | ||||
|     JS_ToInt32(ctx, &height, argv[1]); | ||||
|     const char * title = JS_ToCString(ctx, argv[2]); | ||||
|     if(title == NULL) return JS_EXCEPTION; | ||||
|     InitWindow(width, height, title); | ||||
|     JS_FreeCString(ctx, title); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_setTargetFPS(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     int fps; | ||||
|     JS_ToInt32(ctx, &fps, argv[0]); | ||||
|     SetTargetFPS(fps); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_windowShouldClose(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     app_update_quickjs(); | ||||
|     bool returnVal = WindowShouldClose(); | ||||
|     JSValue ret = JS_NewBool(ctx, returnVal); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_clearBackground(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[0], js_Color_class_id); | ||||
|     if(color_ptr == NULL) return JS_EXCEPTION; | ||||
|     Color color = *color_ptr; | ||||
|     ClearBackground(color); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_closeWindow(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     CloseWindow(); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_drawText(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     const char * text = JS_ToCString(ctx, argv[0]); | ||||
|     if(text == NULL) return JS_EXCEPTION; | ||||
|     int posX; | ||||
|     JS_ToInt32(ctx, &posX, argv[1]); | ||||
|     int posY; | ||||
|     JS_ToInt32(ctx, &posY, argv[2]); | ||||
|     int fontSize; | ||||
|     JS_ToInt32(ctx, &fontSize, argv[3]); | ||||
|     Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[4], js_Color_class_id); | ||||
|     if(color_ptr == NULL) return JS_EXCEPTION; | ||||
|     Color color = *color_ptr; | ||||
|     DrawText(text, posX, posY, fontSize, color); | ||||
|     JS_FreeCString(ctx, text); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_drawCircleV(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     Vector2* center_ptr = (Vector2*)JS_GetOpaque2(ctx, argv[0], js_Vector2_class_id); | ||||
|     if(center_ptr == NULL) return JS_EXCEPTION; | ||||
|     Vector2 center = *center_ptr; | ||||
|     double _double_radius; | ||||
|     JS_ToFloat64(ctx, &_double_radius, argv[1]); | ||||
|     float radius = (float)_double_radius; | ||||
|     Color* color_ptr = (Color*)JS_GetOpaque2(ctx, argv[2], js_Color_class_id); | ||||
|     if(color_ptr == NULL) return JS_EXCEPTION; | ||||
|     Color color = *color_ptr; | ||||
|     DrawCircleV(center, radius, color); | ||||
|     return JS_UNDEFINED; | ||||
| } | ||||
| 
 | ||||
| static JSValue js_isKeyDown(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { | ||||
|     int key; | ||||
|     JS_ToInt32(ctx, &key, argv[0]); | ||||
|     bool returnVal = IsKeyDown(key); | ||||
|     JSValue ret = JS_NewBool(ctx, returnVal); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static const JSCFunctionListEntry js_raylib_core_funcs[] = { | ||||
|     JS_CFUNC_DEF("setWindowTitle",1,js_setWindowTitle), | ||||
|     JS_CFUNC_DEF("setWindowPosition",2,js_setWindowPosition), | ||||
|     JS_CFUNC_DEF("beginDrawing",0,js_beginDrawing), | ||||
|     JS_CFUNC_DEF("endDrawing",0,js_endDrawing), | ||||
|     JS_CFUNC_DEF("initWindow",3,js_initWindow), | ||||
|     JS_CFUNC_DEF("setTargetFPS",1,js_setTargetFPS), | ||||
|     JS_CFUNC_DEF("windowShouldClose",0,js_windowShouldClose), | ||||
|     JS_CFUNC_DEF("clearBackground",1,js_clearBackground), | ||||
|     JS_CFUNC_DEF("closeWindow",0,js_closeWindow), | ||||
|     JS_CFUNC_DEF("drawText",5,js_drawText), | ||||
|     JS_CFUNC_DEF("drawCircleV",3,js_drawCircleV), | ||||
|     JS_CFUNC_DEF("isKeyDown",1,js_isKeyDown), | ||||
| }; | ||||
| 
 | ||||
| static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { | ||||
|  | @ -188,6 +358,165 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { | |||
|     js_declare_Color(ctx, m); | ||||
|     JSValue Color_constr = JS_NewCFunction2(ctx, js_Color_constructor,"Color)", 4, JS_CFUNC_constructor_or_func, 0); | ||||
|     JS_SetModuleExport(ctx, m, "Color", Color_constr); | ||||
|     js_declare_Vector2(ctx, m); | ||||
|     JSValue Vector2_constr = JS_NewCFunction2(ctx, js_Vector2_constructor,"Vector2)", 2, JS_CFUNC_constructor_or_func, 0); | ||||
|     JS_SetModuleExport(ctx, m, "Vector2", Vector2_constr); | ||||
|     Color LIGHTGRAY_struct = { 200, 200, 200, 255 }; | ||||
|     Color* LIGHTGRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *LIGHTGRAY_js_ptr = LIGHTGRAY_struct; | ||||
|     JSValue LIGHTGRAY_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(LIGHTGRAY_js, LIGHTGRAY_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "LIGHTGRAY", LIGHTGRAY_js); | ||||
|     Color GRAY_struct = { 130, 130, 130, 255 }; | ||||
|     Color* GRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *GRAY_js_ptr = GRAY_struct; | ||||
|     JSValue GRAY_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(GRAY_js, GRAY_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "GRAY", GRAY_js); | ||||
|     Color DARKGRAY_struct = { 80, 80, 80, 255 }; | ||||
|     Color* DARKGRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *DARKGRAY_js_ptr = DARKGRAY_struct; | ||||
|     JSValue DARKGRAY_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(DARKGRAY_js, DARKGRAY_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "DARKGRAY", DARKGRAY_js); | ||||
|     Color YELLOW_struct = { 253, 249, 0, 255 }; | ||||
|     Color* YELLOW_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *YELLOW_js_ptr = YELLOW_struct; | ||||
|     JSValue YELLOW_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(YELLOW_js, YELLOW_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "YELLOW", YELLOW_js); | ||||
|     Color GOLD_struct = { 255, 203, 0, 255 }; | ||||
|     Color* GOLD_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *GOLD_js_ptr = GOLD_struct; | ||||
|     JSValue GOLD_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(GOLD_js, GOLD_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "GOLD", GOLD_js); | ||||
|     Color ORANGE_struct = { 255, 161, 0, 255 }; | ||||
|     Color* ORANGE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *ORANGE_js_ptr = ORANGE_struct; | ||||
|     JSValue ORANGE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(ORANGE_js, ORANGE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "ORANGE", ORANGE_js); | ||||
|     Color PINK_struct = { 255, 109, 194, 255 }; | ||||
|     Color* PINK_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *PINK_js_ptr = PINK_struct; | ||||
|     JSValue PINK_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(PINK_js, PINK_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "PINK", PINK_js); | ||||
|     Color RED_struct = { 230, 41, 55, 255 }; | ||||
|     Color* RED_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *RED_js_ptr = RED_struct; | ||||
|     JSValue RED_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(RED_js, RED_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "RED", RED_js); | ||||
|     Color MAROON_struct = { 190, 33, 55, 255 }; | ||||
|     Color* MAROON_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *MAROON_js_ptr = MAROON_struct; | ||||
|     JSValue MAROON_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(MAROON_js, MAROON_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "MAROON", MAROON_js); | ||||
|     Color GREEN_struct = { 0, 228, 48, 255 }; | ||||
|     Color* GREEN_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *GREEN_js_ptr = GREEN_struct; | ||||
|     JSValue GREEN_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(GREEN_js, GREEN_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "GREEN", GREEN_js); | ||||
|     Color LIME_struct = { 0, 158, 47, 255 }; | ||||
|     Color* LIME_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *LIME_js_ptr = LIME_struct; | ||||
|     JSValue LIME_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(LIME_js, LIME_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "LIME", LIME_js); | ||||
|     Color DARKGREEN_struct = { 0, 117, 44, 255 }; | ||||
|     Color* DARKGREEN_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *DARKGREEN_js_ptr = DARKGREEN_struct; | ||||
|     JSValue DARKGREEN_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(DARKGREEN_js, DARKGREEN_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "DARKGREEN", DARKGREEN_js); | ||||
|     Color SKYBLUE_struct = { 102, 191, 255, 255 }; | ||||
|     Color* SKYBLUE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *SKYBLUE_js_ptr = SKYBLUE_struct; | ||||
|     JSValue SKYBLUE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(SKYBLUE_js, SKYBLUE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "SKYBLUE", SKYBLUE_js); | ||||
|     Color BLUE_struct = { 0, 121, 241, 255 }; | ||||
|     Color* BLUE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *BLUE_js_ptr = BLUE_struct; | ||||
|     JSValue BLUE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(BLUE_js, BLUE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "BLUE", BLUE_js); | ||||
|     Color DARKBLUE_struct = { 0, 82, 172, 255 }; | ||||
|     Color* DARKBLUE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *DARKBLUE_js_ptr = DARKBLUE_struct; | ||||
|     JSValue DARKBLUE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(DARKBLUE_js, DARKBLUE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "DARKBLUE", DARKBLUE_js); | ||||
|     Color PURPLE_struct = { 200, 122, 255, 255 }; | ||||
|     Color* PURPLE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *PURPLE_js_ptr = PURPLE_struct; | ||||
|     JSValue PURPLE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(PURPLE_js, PURPLE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "PURPLE", PURPLE_js); | ||||
|     Color VIOLET_struct = { 135, 60, 190, 255 }; | ||||
|     Color* VIOLET_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *VIOLET_js_ptr = VIOLET_struct; | ||||
|     JSValue VIOLET_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(VIOLET_js, VIOLET_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "VIOLET", VIOLET_js); | ||||
|     Color DARKPURPLE_struct = { 112, 31, 126, 255 }; | ||||
|     Color* DARKPURPLE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *DARKPURPLE_js_ptr = DARKPURPLE_struct; | ||||
|     JSValue DARKPURPLE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(DARKPURPLE_js, DARKPURPLE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "DARKPURPLE", DARKPURPLE_js); | ||||
|     Color BEIGE_struct = { 211, 176, 131, 255 }; | ||||
|     Color* BEIGE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *BEIGE_js_ptr = BEIGE_struct; | ||||
|     JSValue BEIGE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(BEIGE_js, BEIGE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "BEIGE", BEIGE_js); | ||||
|     Color BROWN_struct = { 127, 106, 79, 255 }; | ||||
|     Color* BROWN_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *BROWN_js_ptr = BROWN_struct; | ||||
|     JSValue BROWN_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(BROWN_js, BROWN_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "BROWN", BROWN_js); | ||||
|     Color DARKBROWN_struct = { 76, 63, 47, 255 }; | ||||
|     Color* DARKBROWN_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *DARKBROWN_js_ptr = DARKBROWN_struct; | ||||
|     JSValue DARKBROWN_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(DARKBROWN_js, DARKBROWN_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "DARKBROWN", DARKBROWN_js); | ||||
|     Color WHITE_struct = { 255, 255, 255, 255 }; | ||||
|     Color* WHITE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *WHITE_js_ptr = WHITE_struct; | ||||
|     JSValue WHITE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(WHITE_js, WHITE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "WHITE", WHITE_js); | ||||
|     Color BLACK_struct = { 0, 0, 0, 255 }; | ||||
|     Color* BLACK_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *BLACK_js_ptr = BLACK_struct; | ||||
|     JSValue BLACK_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(BLACK_js, BLACK_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "BLACK", BLACK_js); | ||||
|     Color BLANK_struct = { 0, 0, 0, 0 }; | ||||
|     Color* BLANK_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *BLANK_js_ptr = BLANK_struct; | ||||
|     JSValue BLANK_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(BLANK_js, BLANK_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "BLANK", BLANK_js); | ||||
|     Color MAGENTA_struct = { 255, 0, 255, 255 }; | ||||
|     Color* MAGENTA_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *MAGENTA_js_ptr = MAGENTA_struct; | ||||
|     JSValue MAGENTA_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(MAGENTA_js, MAGENTA_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "MAGENTA", MAGENTA_js); | ||||
|     Color RAYWHITE_struct = { 245, 245, 245, 255 }; | ||||
|     Color* RAYWHITE_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); | ||||
|     *RAYWHITE_js_ptr = RAYWHITE_struct; | ||||
|     JSValue RAYWHITE_js = JS_NewObjectClass(ctx, js_Color_class_id); | ||||
|     JS_SetOpaque(RAYWHITE_js, RAYWHITE_js_ptr); | ||||
|     JS_SetModuleExport(ctx, m, "RAYWHITE", RAYWHITE_js); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -197,6 +526,33 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na | |||
|     if(!m) return NULL; | ||||
|     JS_AddModuleExportList(ctx, m, js_raylib_core_funcs, countof(js_raylib_core_funcs)); | ||||
|     JS_AddModuleExport(ctx, m, "Color"); | ||||
|     JS_AddModuleExport(ctx, m, "Vector2"); | ||||
|     JS_AddModuleExport(ctx, m, "LIGHTGRAY"); | ||||
|     JS_AddModuleExport(ctx, m, "GRAY"); | ||||
|     JS_AddModuleExport(ctx, m, "DARKGRAY"); | ||||
|     JS_AddModuleExport(ctx, m, "YELLOW"); | ||||
|     JS_AddModuleExport(ctx, m, "GOLD"); | ||||
|     JS_AddModuleExport(ctx, m, "ORANGE"); | ||||
|     JS_AddModuleExport(ctx, m, "PINK"); | ||||
|     JS_AddModuleExport(ctx, m, "RED"); | ||||
|     JS_AddModuleExport(ctx, m, "MAROON"); | ||||
|     JS_AddModuleExport(ctx, m, "GREEN"); | ||||
|     JS_AddModuleExport(ctx, m, "LIME"); | ||||
|     JS_AddModuleExport(ctx, m, "DARKGREEN"); | ||||
|     JS_AddModuleExport(ctx, m, "SKYBLUE"); | ||||
|     JS_AddModuleExport(ctx, m, "BLUE"); | ||||
|     JS_AddModuleExport(ctx, m, "DARKBLUE"); | ||||
|     JS_AddModuleExport(ctx, m, "PURPLE"); | ||||
|     JS_AddModuleExport(ctx, m, "VIOLET"); | ||||
|     JS_AddModuleExport(ctx, m, "DARKPURPLE"); | ||||
|     JS_AddModuleExport(ctx, m, "BEIGE"); | ||||
|     JS_AddModuleExport(ctx, m, "BROWN"); | ||||
|     JS_AddModuleExport(ctx, m, "DARKBROWN"); | ||||
|     JS_AddModuleExport(ctx, m, "WHITE"); | ||||
|     JS_AddModuleExport(ctx, m, "BLACK"); | ||||
|     JS_AddModuleExport(ctx, m, "BLANK"); | ||||
|     JS_AddModuleExport(ctx, m, "MAGENTA"); | ||||
|     JS_AddModuleExport(ctx, m, "RAYWHITE"); | ||||
|     return m; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -64,10 +64,10 @@ static JSValue js_loadImage(JSContext * ctx, JSValueConst this_val, int argc, JS | |||
|     if(fileName == NULL) return JS_EXCEPTION; | ||||
|     Image returnVal = LoadImage(fileName); | ||||
|     JS_FreeCString(ctx, fileName); | ||||
|     Image* ptr = (Image*)js_malloc(ctx, sizeof(Image)); | ||||
|     *ptr = returnVal; | ||||
|     Image* ret_ptr = (Image*)js_malloc(ctx, sizeof(Image)); | ||||
|     *ret_ptr = returnVal; | ||||
|     JSValue ret = JS_NewObjectClass(ctx, js_Image_class_id); | ||||
|     JS_SetOpaque(ret, ptr); | ||||
|     JS_SetOpaque(ret, ret_ptr); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										62
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										62
									
								
								src/main.c
								
								
								
								
							|  | @ -29,43 +29,45 @@ | |||
| //------------------------------------------------------------------------------------
 | ||||
| int main(int argc, char ** argv) | ||||
| { | ||||
|     // Initialization
 | ||||
|     //--------------------------------------------------------------------------------------
 | ||||
|     const int screenWidth = 800; | ||||
|     const int screenHeight = 450; | ||||
| 
 | ||||
|     InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); | ||||
| 
 | ||||
|     SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
 | ||||
|     //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     app_init_quickjs(argc, argv); | ||||
|     // // Initialization
 | ||||
|     // //--------------------------------------------------------------------------------------
 | ||||
|     // const int screenWidth = 800;
 | ||||
|     // const int screenHeight = 450;
 | ||||
| 
 | ||||
|     // Main game loop
 | ||||
|     while (!WindowShouldClose())    // Detect window close button or ESC key
 | ||||
|     { | ||||
|         app_update_quickjs(); | ||||
|         // Update
 | ||||
|         //----------------------------------------------------------------------------------
 | ||||
|         // TODO: Update your variables here
 | ||||
|         //----------------------------------------------------------------------------------
 | ||||
|     // InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
 | ||||
| 
 | ||||
|         // Draw
 | ||||
|         //----------------------------------------------------------------------------------
 | ||||
|         BeginDrawing(); | ||||
|     // SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
 | ||||
|     // //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|             ClearBackground(RAYWHITE); | ||||
| 
 | ||||
|             DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); | ||||
|     // // Main game loop
 | ||||
|     // while (!WindowShouldClose())    // Detect window close button or ESC key
 | ||||
|     // {
 | ||||
|     //     app_update_quickjs();
 | ||||
|     //     // Update
 | ||||
|     //     //----------------------------------------------------------------------------------
 | ||||
|     //     // TODO: Update your variables here
 | ||||
|     //     //----------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|         EndDrawing(); | ||||
|         //----------------------------------------------------------------------------------
 | ||||
|     } | ||||
|     //     // Draw
 | ||||
|     //     //----------------------------------------------------------------------------------
 | ||||
|     //     BeginDrawing();
 | ||||
| 
 | ||||
|     // De-Initialization
 | ||||
|     //--------------------------------------------------------------------------------------
 | ||||
|     CloseWindow();        // Close window and OpenGL context
 | ||||
|     //--------------------------------------------------------------------------------------
 | ||||
|     //         ClearBackground(RAYWHITE);
 | ||||
| 
 | ||||
|     //         DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
 | ||||
| 
 | ||||
|     //     EndDrawing();
 | ||||
|     //     //----------------------------------------------------------------------------------
 | ||||
|     // }
 | ||||
| 
 | ||||
| 
 | ||||
|     // // De-Initialization
 | ||||
|     // //--------------------------------------------------------------------------------------
 | ||||
|     // CloseWindow();        // Close window and OpenGL context
 | ||||
|     // //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     app_dispose_quickjs(); | ||||
|     return 0; | ||||
| } | ||||
|  | @ -4,8 +4,6 @@ | |||
| #include <raylib.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "bindings/js_raylib_core.h" | ||||
| #include "bindings/js_raylib_texture.h" | ||||
| 
 | ||||
| static JSContext *JS_NewCustomContext(JSRuntime *rt); | ||||
| static int eval_buf(JSContext *ctx, const void *buf, int buf_len, | ||||
|  | @ -14,6 +12,26 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len, | |||
| static JSRuntime* rt; | ||||
| static JSContext* ctx; | ||||
| 
 | ||||
| int app_update_quickjs(){ | ||||
|     JSContext *ctx1; | ||||
|     int err; | ||||
| 
 | ||||
|     /* execute the pending jobs */ | ||||
|     for(;;) { | ||||
|         err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); | ||||
|         if (err <= 0) { | ||||
|             if (err < 0) { | ||||
|                 js_std_dump_error(ctx1); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #include "bindings/js_raylib_core.h" | ||||
| #include "bindings/js_raylib_texture.h" | ||||
| 
 | ||||
| int app_init_quickjs(int argc, char** argv){ | ||||
|     rt = JS_NewRuntime(); | ||||
|     if (!rt) | ||||
|  | @ -39,14 +57,14 @@ int app_init_quickjs(int argc, char** argv){ | |||
|     //             "globalThis.os = os;\n";
 | ||||
|     // eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
 | ||||
| 
 | ||||
|     const char* filename = "main.js"; | ||||
|     const char* filename = argc > 1 ? argv[1] : "main.js"; | ||||
|     const char* buf = LoadFileText(filename); | ||||
|     size_t len = strlen(buf); | ||||
|     if (!buf) { | ||||
|         JS_ThrowReferenceError(ctx, "could not load module filename '%s'", | ||||
|                                 filename); | ||||
|         return -1; | ||||
|     } | ||||
|     size_t len = strlen(buf); | ||||
|     int res = eval_buf(ctx, buf, len, "main", JS_EVAL_TYPE_MODULE); | ||||
|     if(res){ | ||||
|         return res; | ||||
|  | @ -54,22 +72,7 @@ int app_init_quickjs(int argc, char** argv){ | |||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int app_update_quickjs(){ | ||||
|     JSContext *ctx1; | ||||
|     int err; | ||||
| 
 | ||||
|     /* execute the pending jobs */ | ||||
|     for(;;) { | ||||
|         err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); | ||||
|         if (err <= 0) { | ||||
|             if (err < 0) { | ||||
|                 js_std_dump_error(ctx1); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int app_dispose_quickjs(){ | ||||
|     //js_std_free_handlers(rt);
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue