2023-05-06 21:43:40 +00:00
/******/ ( ( ) => { // webpackBootstrap
/******/ "use strict" ;
/******/ var _ _webpack _modules _ _ = ( {
/***/ "./src/generation.ts" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / generation . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( _ _unused _webpack _module , exports ) => {
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
2023-05-08 14:43:50 +00:00
exports . CodeGenerator = exports . GenericCodeGenerator = exports . CodeWriter = exports . StringWriter = void 0 ;
2023-05-06 21:43:40 +00:00
class StringWriter {
constructor ( ) {
this . buffer = '' ;
}
write ( value ) {
this . buffer += value ;
}
writeLine ( value = '' ) {
this . buffer += value + '\n' ;
}
toString ( ) {
return this . buffer ;
}
}
exports . StringWriter = StringWriter ;
class CodeWriter extends StringWriter {
constructor ( ) {
super ( ... arguments ) ;
this . indent = 0 ;
this . needsIndent = true ;
}
writeGenerator ( generator ) {
const tokens = generator . iterateTokens ( ) ;
const text = generator . iterateText ( ) ;
const children = generator . iterateChildren ( ) ;
let result = tokens . next ( ) ;
while ( ! result . done ) {
switch ( result . value ) {
case Token . STRING :
const str = text . next ( ) . value ;
if ( this . needsIndent ) {
this . write ( " " . repeat ( this . indent ) ) ;
this . needsIndent = false ;
}
this . write ( str ) ;
break ;
case Token . GOSUB :
const sub = children . next ( ) . value ;
this . writeGenerator ( sub ) ;
break ;
case Token . INDENT :
this . indent ++ ;
break ;
case Token . UNINDENT :
this . indent = this . indent > 0 ? this . indent - 1 : 0 ;
break ;
case Token . NEWLINE :
this . write ( "\n" ) ;
this . needsIndent = true ;
break ;
default :
break ;
}
result = tokens . next ( ) ;
}
}
}
exports . CodeWriter = CodeWriter ;
var Token ;
( function ( Token ) {
Token [ Token [ "STRING" ] = 0 ] = "STRING" ;
Token [ Token [ "NEWLINE" ] = 1 ] = "NEWLINE" ;
Token [ Token [ "INDENT" ] = 2 ] = "INDENT" ;
Token [ Token [ "UNINDENT" ] = 3 ] = "UNINDENT" ;
Token [ Token [ "GOSUB" ] = 4 ] = "GOSUB" ;
} ) ( Token || ( Token = { } ) ) ;
2023-05-08 14:43:50 +00:00
class GenericCodeGenerator {
2023-05-06 21:43:40 +00:00
constructor ( ) {
this . children = [ ] ;
this . text = [ ] ;
this . tokens = [ ] ;
2023-05-08 14:43:50 +00:00
this . tags = { } ;
}
getTag ( key ) {
return this . tags [ key ] ;
}
setTag ( key , value ) {
this . tags [ key ] = value ;
2023-05-06 21:43:40 +00:00
}
iterateTokens ( ) {
return this . tokens [ Symbol . iterator ] ( ) ;
}
iterateText ( ) {
return this . text [ Symbol . iterator ] ( ) ;
}
iterateChildren ( ) {
return this . children [ Symbol . iterator ] ( ) ;
}
line ( text ) {
this . tokens . push ( Token . STRING , Token . NEWLINE ) ;
this . text . push ( text ) ;
}
comment ( text ) {
this . line ( "// " + text ) ;
}
call ( name , params , returnVal = null ) {
if ( returnVal )
this . inline ( ` ${ returnVal . type } ${ returnVal . name } = ` ) ;
this . inline ( name + "(" ) ;
this . inline ( params . join ( ", " ) ) ;
this . statement ( ")" ) ;
}
declare ( name , type , isStatic = false , initValue = null ) {
if ( isStatic )
this . inline ( "static " ) ;
this . inline ( type + " " + name ) ;
if ( initValue )
this . inline ( " = " + initValue ) ;
this . statement ( "" ) ;
}
child ( sub ) {
2023-05-08 14:43:50 +00:00
if ( ! sub )
sub = this . createGenerator ( ) ;
2023-05-06 21:43:40 +00:00
this . tokens . push ( Token . GOSUB ) ;
this . children . push ( sub ) ;
2023-05-08 14:43:50 +00:00
return sub ;
2023-05-06 21:43:40 +00:00
}
inline ( str ) {
this . tokens . push ( Token . STRING ) ;
this . text . push ( str ) ;
}
statement ( str ) {
this . line ( str + ";" ) ;
}
breakLine ( ) {
this . tokens . push ( Token . NEWLINE ) ;
}
indent ( ) {
this . tokens . push ( Token . INDENT ) ;
}
unindent ( ) {
this . tokens . push ( Token . UNINDENT ) ;
}
2023-05-08 14:43:50 +00:00
function ( name , returnType , args , isStatic , func ) {
const sub = this . createGenerator ( ) ;
sub . setTag ( "_type" , "function-body" ) ;
sub . setTag ( "_name" , name ) ;
sub . setTag ( "_isStatic" , isStatic ) ;
sub . setTag ( "_returnType" , returnType ) ;
if ( isStatic )
this . inline ( "static " ) ;
this . inline ( returnType + " " + name + "(" ) ;
this . inline ( args . map ( x => x . type + " " + x . name ) . join ( ", " ) ) ;
this . inline ( ") {" ) ;
this . breakLine ( ) ;
this . indent ( ) ;
this . child ( sub ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
this . breakLine ( ) ;
if ( func )
func ( sub ) ;
return sub ;
}
if ( condition , funIf ) {
2023-05-06 21:43:40 +00:00
this . line ( "if(" + condition + ") {" ) ;
this . indent ( ) ;
2023-05-08 14:43:50 +00:00
const sub = this . createGenerator ( ) ;
sub . setTag ( "_type" , "if-body" ) ;
sub . setTag ( "_condition" , condition ) ;
this . child ( sub ) ;
2023-05-06 21:43:40 +00:00
this . unindent ( ) ;
this . line ( "}" ) ;
2023-05-08 14:43:50 +00:00
if ( funIf )
funIf ( sub ) ;
return sub ;
2023-05-06 21:43:40 +00:00
}
2023-05-08 14:43:50 +00:00
else ( funElse ) {
this . line ( "else {" ) ;
this . indent ( ) ;
const sub = this . createGenerator ( ) ;
sub . setTag ( "_type" , "else-body" ) ;
this . child ( sub ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
if ( funElse )
funElse ( sub ) ;
return sub ;
2023-05-06 21:43:40 +00:00
}
2023-05-08 14:43:50 +00:00
returnExp ( exp ) {
this . statement ( "return " + exp ) ;
2023-05-06 21:43:40 +00:00
}
include ( name ) {
this . line ( "#include <" + name + ">" ) ;
}
2023-06-02 06:03:36 +00:00
for ( indexVar , lengthVar ) {
this . line ( ` for(int ${ indexVar } ; i < ${ lengthVar } ; i++){ ` ) ;
this . indent ( ) ;
const child = this . child ( ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
return child ;
}
2023-05-08 14:43:50 +00:00
header ( guard , fun ) {
this . line ( "#ifndef " + guard ) ;
this . line ( "#define " + guard ) ;
this . breakLine ( ) ;
const sub = this . child ( ) ;
sub . setTag ( "_type" , "header-body" ) ;
sub . setTag ( "_guardName" , guard ) ;
this . line ( "#endif // " + guard ) ;
if ( fun )
fun ( sub ) ;
return sub ;
}
2023-05-10 21:26:53 +00:00
declareStruct ( structName , varName , values , isStatic = false ) {
if ( isStatic )
this . inline ( "static " ) ;
this . statement ( ` ${ structName } ${ varName } = { ${ values . join ( ', ' ) } } ` ) ;
}
2023-05-16 06:28:30 +00:00
switch ( switchVar ) {
this . line ( ` switch( ${ switchVar } ) { ` ) ;
this . indent ( ) ;
const body = this . child ( ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
return body ;
}
case ( value ) {
this . line ( ` case ${ value } : ` ) ;
}
defaultBreak ( ) {
this . line ( "default:" ) ;
this . line ( "{" ) ;
this . indent ( ) ;
const body = this . child ( ) ;
this . statement ( "break" ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
return body ;
}
caseBreak ( value ) {
this . case ( value ) ;
this . line ( "{" ) ;
this . indent ( ) ;
const body = this . child ( ) ;
this . statement ( "break" ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
return body ;
}
2023-05-08 14:43:50 +00:00
}
exports . GenericCodeGenerator = GenericCodeGenerator ;
class CodeGenerator extends GenericCodeGenerator {
createGenerator ( ) {
return new CodeGenerator ( ) ;
}
2023-05-06 21:43:40 +00:00
}
2023-05-08 14:43:50 +00:00
exports . CodeGenerator = CodeGenerator ;
2023-05-26 20:09:53 +00:00
/***/ } ) ,
/***/ "./src/header-parser.ts" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / header - parser . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( _ _unused _webpack _module , exports ) => {
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
exports . HeaderParser = void 0 ;
class HeaderParser {
parseEnums ( input ) {
const matches = [ ... input . matchAll ( /((?:\/\/.+\n)*)typedef enum {\n([^}]+)} ([^;]+)/gm ) ] ;
return matches . map ( groups => {
return {
description : this . parseComments ( groups [ 1 ] ) ,
values : this . parseEnumValues ( groups [ 2 ] ) ,
name : groups [ 3 ] ,
} ;
} ) ;
}
parseEnumValues ( input ) {
let lastNumber = 0 ;
return input . split ( '\n' )
. map ( line => line . trim ( ) . match ( /([^ ,]+)(?: = ([0-9]+))?,?(?: *)(?:\/\/ (.+))?/ ) )
. filter ( x => x !== null && ! x [ 0 ] . startsWith ( "/" ) )
. map ( groups => {
let val = lastNumber = groups [ 2 ] ? parseInt ( groups [ 2 ] ) : lastNumber ;
lastNumber ++ ;
return {
name : groups [ 1 ] ,
description : groups [ 3 ] || "" ,
value : val
} ;
} ) ;
}
parseComments ( input ) {
return input . split ( '\n' ) . map ( x => x . replace ( "// " , "" ) ) . join ( '\n' ) . trim ( ) ;
}
parseFunctionDefinitions ( input ) {
2023-05-26 22:47:44 +00:00
const matches = [ ... input . matchAll ( /^[A-Z]+ (.+?)(\w+)\(([^\)]+)\);(?: +\/\/ (.+))?$/gm ) ] ;
2023-05-26 20:09:53 +00:00
return matches . map ( groups => ( {
returnType : groups [ 1 ] . trim ( ) ,
name : groups [ 2 ] ,
params : this . parseFunctionArgs ( groups [ 3 ] ) ,
description : groups [ 4 ] || ""
} ) ) ;
}
2023-05-26 22:47:44 +00:00
parseFunctions ( input , noPrefix = false ) {
const matches = noPrefix
? [ ... input . matchAll ( /((?:\/\/.+\n)+)^(.+?)(\w+)\(([^\)]+)\)/gm ) ]
: [ ... input . matchAll ( /((?:\/\/.+\n)+)^[A-Z]+ (.+?)(\w+)\(([^\)]+)\)/gm ) ] ;
2023-05-26 20:09:53 +00:00
return matches . map ( groups => ( {
2023-05-26 22:47:44 +00:00
returnType : groups [ 2 ] . trim ( ) ,
name : groups [ 3 ] ,
params : this . parseFunctionArgs ( groups [ 4 ] ) ,
description : groups [ 1 ] ? this . parseComments ( groups [ 1 ] ) : ""
2023-05-26 20:09:53 +00:00
} ) ) ;
}
parseFunctionArgs ( input ) {
return input . split ( ',' ) . filter ( x => x !== 'void' ) . map ( arg => {
arg = arg . trim ( ) . replace ( " *" , "* " ) ;
const frags = arg . split ( ' ' ) ;
const name = frags . pop ( ) ;
const type = frags . join ( ' ' ) . replace ( "*" , " *" ) ;
return { name : name || "" , type : type . trim ( ) } ;
} ) ;
}
2023-06-11 10:49:26 +00:00
parseStructs ( input ) {
return [ ... input . matchAll ( /((?:\/\/.+\n)+)typedef struct {([^}]+)} ([^;]+);/gm ) ] . map ( groups => ( {
name : groups [ 3 ] ,
fields : this . parseStructFields ( groups [ 2 ] ) ,
description : this . parseComments ( groups [ 1 ] )
} ) ) ;
}
parseStructFields ( input ) {
return input . trim ( ) . split ( "\n" ) . map ( x => x . trim ( ) ) . filter ( x => ! x . startsWith ( "/" ) && x . endsWith ( ";" ) ) . map ( x => {
const match = x . match ( /([^ ]+(?: \*)?) ([^;]+);/ ) ;
return {
name : match [ 2 ] ,
type : match [ 1 ] ,
description : ""
} ;
} ) ;
}
2023-05-26 20:09:53 +00:00
}
exports . HeaderParser = HeaderParser ;
2023-05-08 14:43:50 +00:00
/***/ } ) ,
/***/ "./src/quickjs.ts" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / quickjs . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( _ _unused _webpack _module , exports , _ _webpack _require _ _ ) => {
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
exports . QuickJsGenerator = exports . GenericQuickJsGenerator = exports . QuickJsHeader = void 0 ;
const fs _1 = _ _webpack _require _ _ ( /*! fs */ "fs" ) ;
const generation _1 = _ _webpack _require _ _ ( /*! ./generation */ "./src/generation.ts" ) ;
class QuickJsHeader {
constructor ( name ) {
2023-05-06 21:43:40 +00:00
this . name = name ;
2023-05-08 21:37:58 +00:00
this . structLookup = { } ;
2023-05-08 14:43:50 +00:00
const root = this . root = new QuickJsGenerator ( ) ;
const body = this . body = root . header ( "JS_" + this . name + "_GUARD" ) ;
const includes = this . includes = body . child ( ) ;
includes . include ( "stdio.h" ) ;
includes . include ( "stdlib.h" ) ;
includes . include ( "string.h" ) ;
includes . breakLine ( ) ;
includes . include ( "quickjs.h" ) ;
body . breakLine ( ) ;
body . line ( "#ifndef countof" ) ;
body . line ( "#define countof(x) (sizeof(x) / sizeof((x)[0]))" ) ;
body . line ( "#endif" ) ;
body . breakLine ( ) ;
2023-05-14 20:19:47 +00:00
this . definitions = body . child ( ) ;
2023-05-08 14:43:50 +00:00
body . breakLine ( ) ;
this . structs = body . child ( ) ;
this . functions = body . child ( ) ;
this . moduleFunctionList = body . jsFunctionList ( "js_" + name + "_funcs" ) ;
const moduleInitFunc = body . function ( "js_" + this . name + "_init" , "int" , [ { type : "JSContext *" , name : "ctx" } , { type : "JSModuleDef *" , name : "m" } ] , true ) ;
const moduleInit = this . moduleInit = moduleInitFunc . child ( ) ;
moduleInit . statement ( ` JS_SetModuleExportList(ctx, m, ${ this . moduleFunctionList . getTag ( "_name" ) } ,countof( ${ this . moduleFunctionList . getTag ( "_name" ) } )) ` ) ;
moduleInitFunc . returnExp ( "0" ) ;
const moduleEntryFunc = body . function ( "js_init_module_" + this . name , "JSModuleDef *" , [ { type : "JSContext *" , name : "ctx" } , { type : "const char *" , name : "module_name" } ] , false ) ;
const moduleEntry = this . moduleEntry = moduleEntryFunc . child ( ) ;
moduleEntry . statement ( "JSModuleDef *m" ) ;
moduleEntry . statement ( ` m = JS_NewCModule(ctx, module_name, ${ moduleInitFunc . getTag ( "_name" ) } ) ` ) ;
moduleEntry . statement ( "if(!m) return NULL" ) ;
moduleEntry . statement ( ` JS_AddModuleExportList(ctx, m, ${ this . moduleFunctionList . getTag ( "_name" ) } , countof( ${ this . moduleFunctionList . getTag ( "_name" ) } )) ` ) ;
moduleEntryFunc . statement ( "return m" ) ;
}
2023-05-08 21:37:58 +00:00
registerStruct ( struct , classId ) {
this . structLookup [ struct ] = classId ;
}
2023-05-08 14:43:50 +00:00
writeTo ( filename ) {
const writer = new generation _1 . CodeWriter ( ) ;
writer . writeGenerator ( this . root ) ;
( 0 , fs _1 . writeFileSync ) ( filename , writer . toString ( ) ) ;
}
}
exports . QuickJsHeader = QuickJsHeader ;
class GenericQuickJsGenerator extends generation _1 . GenericCodeGenerator {
jsBindingFunction ( jsName ) {
const args = [
{ type : "JSContext *" , name : "ctx" } ,
{ type : "JSValueConst" , name : "this_val" } ,
{ type : "int" , name : "argc" } ,
{ type : "JSValueConst *" , name : "argv" } ,
] ;
const sub = this . function ( "js_" + jsName , "JSValue" , args , true ) ;
return sub ;
}
2023-06-03 07:15:38 +00:00
jsToC ( type , name , src , classIds = { } , supressDeclaration = false , typeAlias ) {
switch ( typeAlias ? ? type ) {
2023-05-20 19:34:27 +00:00
// Array Buffer
case "const void *" :
case "void *" :
case "float *" :
case "unsigned short *" :
case "unsigned char *" :
2023-05-24 20:47:17 +00:00
case "const unsigned char *" :
2023-05-20 19:34:27 +00:00
this . declare ( name + "_size" , "size_t" ) ;
this . declare ( name + "_js" , "void *" , false , ` (void *)JS_GetArrayBuffer(ctx, & ${ name } _size, ${ src } ) ` ) ;
this . if ( name + "_js == NULL" ) . returnExp ( "JS_EXCEPTION" ) ;
this . declare ( name , type , false , "malloc(" + name + "_size)" ) ;
this . call ( "memcpy" , [ "(void *)" + name , "(const void *)" + name + "_js" , name + "_size" ] ) ;
break ;
// String
2023-05-08 14:43:50 +00:00
case "const char *" :
2023-06-03 07:15:38 +00:00
//case "char *":
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
2023-06-06 14:50:38 +00:00
this . statement ( ` ${ type } ${ name } = (JS_IsNull( ${ src } ) || JS_IsUndefined( ${ src } )) ? NULL : ( ${ type } )JS_ToCString(ctx, ${ src } ) ` ) ;
2023-05-16 09:59:29 +00:00
else
2023-06-06 14:50:38 +00:00
this . statement ( ` ${ name } = (JS_IsNull( ${ src } ) || JS_IsUndefined( ${ src } )) ? NULL : ( ${ type } )JS_ToCString(ctx, ${ src } ) ` ) ;
2023-05-08 14:43:50 +00:00
break ;
2023-05-14 20:19:47 +00:00
case "double" :
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } ` ) ;
2023-05-14 20:19:47 +00:00
this . statement ( ` JS_ToFloat64(ctx, & ${ name } , ${ src } ) ` ) ;
break ;
2023-05-10 21:26:53 +00:00
case "float" :
this . statement ( "double _double_" + name ) ;
this . statement ( ` JS_ToFloat64(ctx, &_double_ ${ name } , ${ src } ) ` ) ;
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } = ( ${ type } )_double_ ${ name } ` ) ;
else
this . statement ( ` ${ name } = ( ${ type } )_double_ ${ name } ` ) ;
2023-05-10 21:26:53 +00:00
break ;
2023-05-08 14:43:50 +00:00
case "int" :
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } ` ) ;
2023-05-14 20:19:47 +00:00
this . statement ( ` JS_ToInt32(ctx, & ${ name } , ${ src } ) ` ) ;
break ;
2023-05-13 12:49:05 +00:00
case "unsigned int" :
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } ` ) ;
2023-05-14 20:19:47 +00:00
this . statement ( ` JS_ToUint32(ctx, & ${ name } , ${ src } ) ` ) ;
2023-05-08 16:05:03 +00:00
break ;
2023-05-08 21:37:58 +00:00
case "unsigned char" :
2023-05-14 20:19:47 +00:00
this . statement ( "unsigned int _int_" + name ) ;
this . statement ( ` JS_ToUint32(ctx, &_int_ ${ name } , ${ src } ) ` ) ;
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } = ( ${ type } )_int_ ${ name } ` ) ;
else
this . statement ( ` ${ name } = ( ${ type } )_int_ ${ name } ` ) ;
2023-05-08 21:37:58 +00:00
break ;
2023-05-14 20:19:47 +00:00
case "bool" :
2023-05-16 09:59:29 +00:00
if ( ! supressDeclaration )
this . statement ( ` ${ type } ${ name } = JS_ToBool(ctx, ${ src } ) ` ) ;
else
this . statement ( ` ${ name } = JS_ToBool(ctx, ${ src } ) ` ) ;
2023-05-14 20:19:47 +00:00
break ;
2023-05-08 16:05:03 +00:00
default :
2023-05-14 20:19:47 +00:00
const isConst = type . startsWith ( 'const' ) ;
2023-05-15 21:02:41 +00:00
const isPointer = type . endsWith ( ' *' ) ;
const classId = classIds [ type . replace ( "const " , "" ) . replace ( " *" , "" ) ] ;
2023-05-10 21:26:53 +00:00
if ( ! classId )
throw new Error ( "Cannot convert into parameter type: " + type ) ;
2023-05-15 21:02:41 +00:00
const suffix = isPointer ? "" : "_ptr" ;
this . jsOpqToStructPtr ( type . replace ( " *" , "" ) , name + suffix , src , classId ) ;
this . statement ( ` if( ${ name + suffix } == NULL) return JS_EXCEPTION ` ) ;
if ( ! isPointer )
this . declare ( name , type , false , ` * ${ name } _ptr ` ) ;
2023-05-08 16:05:03 +00:00
}
}
2023-05-08 21:37:58 +00:00
jsToJs ( type , name , src , classIds = { } ) {
2023-05-08 16:05:03 +00:00
switch ( type ) {
case "int" :
2023-05-13 12:49:05 +00:00
case "long" :
2023-05-08 21:37:58 +00:00
this . declare ( name , 'JSValue' , false , ` JS_NewInt32(ctx, ${ src } ) ` ) ;
2023-05-08 14:43:50 +00:00
break ;
2023-05-14 20:19:47 +00:00
case "long" :
this . declare ( name , 'JSValue' , false , ` JS_NewInt64(ctx, ${ src } ) ` ) ;
break ;
case "unsigned int" :
case "unsigned char" :
this . declare ( name , 'JSValue' , false , ` JS_NewUint32(ctx, ${ src } ) ` ) ;
break ;
2023-05-10 21:26:53 +00:00
case "bool" :
this . declare ( name , 'JSValue' , false , ` JS_NewBool(ctx, ${ src } ) ` ) ;
break ;
case "float" :
2023-05-13 12:49:05 +00:00
case "double" :
2023-05-10 21:26:53 +00:00
this . declare ( name , 'JSValue' , false , ` JS_NewFloat64(ctx, ${ src } ) ` ) ;
break ;
2023-05-13 12:49:05 +00:00
case "const char *" :
case "char *" :
this . declare ( name , 'JSValue' , false , ` JS_NewString(ctx, ${ src } ) ` ) ;
break ;
2023-05-24 20:47:17 +00:00
// case "unsigned char *":
// this.declare(name, 'JSValue', false, `JS_NewString(ctx, ${src})`)
// break;
2023-05-08 14:43:50 +00:00
default :
2023-05-08 21:37:58 +00:00
const classId = classIds [ type ] ;
if ( ! classId )
2023-05-10 21:26:53 +00:00
throw new Error ( "Cannot convert parameter type to Javascript: " + type ) ;
2023-05-08 21:37:58 +00:00
this . jsStructToOpq ( type , name , src , classId ) ;
2023-05-08 14:43:50 +00:00
}
}
2023-05-08 21:37:58 +00:00
jsStructToOpq ( structType , jsVar , srcVar , classId ) {
2023-05-10 21:26:53 +00:00
this . declare ( jsVar + "_ptr" , structType + "*" , false , ` ( ${ structType } *)js_malloc(ctx, sizeof( ${ structType } )) ` ) ;
this . statement ( "*" + jsVar + "_ptr = " + srcVar ) ;
2023-05-08 21:37:58 +00:00
this . declare ( jsVar , "JSValue" , false , ` JS_NewObjectClass(ctx, ${ classId } ) ` ) ;
2023-05-10 21:26:53 +00:00
this . call ( "JS_SetOpaque" , [ jsVar , jsVar + "_ptr" ] ) ;
2023-05-08 21:37:58 +00:00
}
2023-05-08 14:43:50 +00:00
jsCleanUpParameter ( type , name ) {
switch ( type ) {
2023-05-20 19:34:27 +00:00
case "char *" :
2023-05-08 14:43:50 +00:00
case "const char *" :
this . statement ( ` JS_FreeCString(ctx, ${ name } ) ` ) ;
break ;
2023-05-20 19:34:27 +00:00
case "const void *" :
case "void *" :
case "float *" :
case "unsigned short *" :
case "unsigned char *" :
2023-05-24 20:47:17 +00:00
case "const unsigned char *" :
2023-05-20 19:34:27 +00:00
this . statement ( ` free((void *) ${ name } ) ` ) ;
break ;
2023-05-08 14:43:50 +00:00
default :
break ;
}
}
jsFunctionList ( name ) {
this . line ( "static const JSCFunctionListEntry " + name + "[] = {" ) ;
2023-05-06 21:43:40 +00:00
this . indent ( ) ;
2023-05-08 14:43:50 +00:00
const sub = this . createGenerator ( ) ;
sub . setTag ( "_type" , "js-function-list" ) ;
sub . setTag ( "_name" , name ) ;
this . child ( sub ) ;
2023-05-06 21:43:40 +00:00
this . unindent ( ) ;
2023-05-08 14:43:50 +00:00
this . statement ( "}" ) ;
this . breakLine ( ) ;
return sub ;
}
jsFuncDef ( jsName , numArgs , cName ) {
this . line ( ` JS_CFUNC_DEF(" ${ jsName } ", ${ numArgs } , ${ cName } ), ` ) ;
}
jsClassId ( id ) {
this . declare ( id , "JSClassID" , true ) ;
return id ;
}
jsPropStringDef ( key , value ) {
this . line ( ` JS_PROP_STRING_DEF(" ${ key } "," ${ value } ", JS_PROP_CONFIGURABLE), ` ) ;
}
2023-05-08 16:05:03 +00:00
jsGetSetDef ( key , getFunc , setFunc ) {
this . line ( ` JS_CGETSET_DEF(" ${ key } ", ${ getFunc || "NULL" } , ${ setFunc || "NULL" } ), ` ) ;
}
2023-05-08 14:43:50 +00:00
jsStructFinalizer ( classId , structName , onFinalize ) {
const args = [ { type : "JSRuntime *" , name : "rt" } , { type : "JSValue" , name : "val" } ] ;
const body = this . function ( ` js_ ${ structName } _finalizer ` , "void" , args , true ) ;
body . statement ( ` ${ structName } * ptr = JS_GetOpaque(val, ${ classId } ) ` ) ;
body . if ( "ptr" , cond => {
2023-05-20 19:34:27 +00:00
//cond.call("TraceLog", ["LOG_INFO",`"Finalize ${structName} %p"`,"ptr"])
2023-05-08 14:43:50 +00:00
if ( onFinalize )
onFinalize ( cond , "ptr" ) ;
cond . call ( "js_free_rt" , [ "rt" , "ptr" ] ) ;
} ) ;
return body ;
}
jsClassDeclaration ( structName , classId , finalizerName , funcListName ) {
const body = this . function ( "js_declare_" + structName , "int" , [ { type : "JSContext *" , name : "ctx" } , { type : "JSModuleDef *" , name : "m" } ] , true ) ;
body . call ( "JS_NewClassID" , [ "&" + classId ] ) ;
const classDefName = ` js_ ${ structName } _def ` ;
body . declare ( classDefName , "JSClassDef" , false , ` { .class_name = " ${ structName } ", .finalizer = ${ finalizerName } } ` ) ;
body . call ( "JS_NewClass" , [ "JS_GetRuntime(ctx)" , classId , "&" + classDefName ] ) ;
body . declare ( "proto" , "JSValue" , false , "JS_NewObject(ctx)" ) ;
body . call ( "JS_SetPropertyFunctionList" , [ "ctx" , "proto" , funcListName , ` countof( ${ funcListName } ) ` ] ) ;
body . call ( "JS_SetClassProto" , [ "ctx" , classId , "proto" ] ) ;
body . statement ( "return 0" ) ;
return body ;
}
2023-06-12 15:38:31 +00:00
jsStructGetter ( structName , classId , field , type , classIds , overrideRead ) {
2023-05-08 14:43:50 +00:00
const args = [ { type : "JSContext*" , name : "ctx" } , { type : "JSValueConst" , name : "this_val" } ] ;
const fun = this . function ( ` js_ ${ structName } _get_ ${ field } ` , "JSValue" , args , true ) ;
fun . declare ( "ptr" , structName + "*" , false , ` JS_GetOpaque2(ctx, this_val, ${ classId } ) ` ) ;
2023-06-12 15:38:31 +00:00
if ( overrideRead ) {
overrideRead ( fun ) ;
}
else {
fun . declare ( field , type , false , "ptr->" + field ) ;
}
2023-05-13 12:49:05 +00:00
fun . jsToJs ( type , "ret" , field , classIds ) ;
2023-05-08 14:43:50 +00:00
fun . returnExp ( "ret" ) ;
2023-05-08 16:05:03 +00:00
return fun ;
2023-05-06 21:43:40 +00:00
}
2023-06-12 15:38:31 +00:00
jsStructSetter ( structName , classId , field , type , classIds , overrideWrite ) {
2023-05-08 21:37:58 +00:00
const args = [ { type : "JSContext*" , name : "ctx" } , { type : "JSValueConst" , name : "this_val" } , { type : "JSValueConst" , name : "v" } ] ;
const fun = this . function ( ` js_ ${ structName } _set_ ${ field } ` , "JSValue" , args , true ) ;
fun . declare ( "ptr" , structName + "*" , false , ` JS_GetOpaque2(ctx, this_val, ${ classId } ) ` ) ;
2023-05-13 12:49:05 +00:00
fun . jsToC ( type , "value" , "v" , classIds ) ;
2023-06-12 15:38:31 +00:00
if ( overrideWrite ) {
overrideWrite ( fun ) ;
}
else {
fun . statement ( "ptr->" + field + " = value" ) ;
}
2023-05-08 21:37:58 +00:00
fun . returnExp ( "JS_UNDEFINED" ) ;
return fun ;
}
2023-05-10 21:26:53 +00:00
jsOpqToStructPtr ( structType , structVar , srcVar , classId ) {
this . declare ( structVar , structType + "*" , false , ` ( ${ structType } *)JS_GetOpaque2(ctx, ${ srcVar } , ${ classId } ) ` ) ;
}
2023-05-13 12:49:05 +00:00
jsStructConstructor ( structName , fields , classId , classIds ) {
2023-05-09 21:25:28 +00:00
const body = this . jsBindingFunction ( structName + "_constructor" ) ;
for ( let i = 0 ; i < fields . length ; i ++ ) {
const para = fields [ i ] ;
2023-05-13 12:49:05 +00:00
body . jsToC ( para . type , para . name , "argv[" + i + "]" , classIds ) ;
2023-05-09 21:25:28 +00:00
}
2023-05-10 21:26:53 +00:00
body . declareStruct ( structName , "_struct" , fields . map ( x => x . name ) ) ;
2023-05-09 21:25:28 +00:00
body . jsStructToOpq ( structName , "_return" , "_struct" , classId ) ;
body . returnExp ( "_return" ) ;
return body ;
}
2023-05-06 21:43:40 +00:00
}
2023-05-08 14:43:50 +00:00
exports . GenericQuickJsGenerator = GenericQuickJsGenerator ;
class QuickJsGenerator extends GenericQuickJsGenerator {
createGenerator ( ) {
return new QuickJsGenerator ( ) ;
2023-05-06 21:43:40 +00:00
}
}
2023-05-08 14:43:50 +00:00
exports . QuickJsGenerator = QuickJsGenerator ;
2023-05-06 21:43:40 +00:00
/***/ } ) ,
2023-05-08 14:43:50 +00:00
/***/ "./src/raylib-header.ts" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / raylib - header . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2023-05-06 21:43:40 +00:00
/***/ ( ( _ _unused _webpack _module , exports , _ _webpack _require _ _ ) => {
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
2023-05-08 14:43:50 +00:00
exports . RayLibHeader = void 0 ;
const quickjs _1 = _ _webpack _require _ _ ( /*! ./quickjs */ "./src/quickjs.ts" ) ;
2023-05-14 20:19:47 +00:00
const typescript _1 = _ _webpack _require _ _ ( /*! ./typescript */ "./src/typescript.ts" ) ;
2023-05-08 14:43:50 +00:00
class RayLibHeader extends quickjs _1 . QuickJsHeader {
2023-06-02 09:52:33 +00:00
constructor ( name ) {
2023-05-08 14:43:50 +00:00
super ( name ) ;
2023-05-14 20:19:47 +00:00
this . typings = new typescript _1 . TypeScriptDeclaration ( ) ;
2023-05-08 14:43:50 +00:00
this . includes . include ( "raylib.h" ) ;
2023-05-15 15:44:28 +00:00
//this.includes.line("#define RAYMATH_IMPLEMENTATION")
2023-05-08 14:43:50 +00:00
}
2023-06-02 09:52:33 +00:00
addApiFunction ( api ) {
const options = api . binding || { } ;
if ( options . ignore )
return ;
const jName = options . jsName || api . name . charAt ( 0 ) . toLowerCase ( ) + api . name . slice ( 1 ) ;
2023-06-02 16:58:53 +00:00
console . log ( "Binding function " + api . name ) ;
2023-05-08 14:43:50 +00:00
const fun = this . functions . jsBindingFunction ( jName ) ;
2023-05-16 06:28:30 +00:00
if ( options . body ) {
options . body ( fun ) ;
2023-05-08 14:43:50 +00:00
}
else {
2023-05-16 06:28:30 +00:00
if ( options . before )
options . before ( fun ) ;
// read parameters
2023-06-02 09:52:33 +00:00
api . params = api . params || [ ] ;
2023-06-04 20:31:15 +00:00
const activeParams = api . params . filter ( x => ! x . binding ? . ignore ) ;
for ( let i = 0 ; i < activeParams . length ; i ++ ) {
const para = activeParams [ i ] ;
2023-06-03 07:15:38 +00:00
if ( para . binding ? . customConverter )
2023-06-04 20:31:15 +00:00
para . binding . customConverter ( fun , "argv[" + i + "]" ) ;
2023-06-03 07:15:38 +00:00
else
fun . jsToC ( para . type , para . name , "argv[" + i + "]" , this . structLookup , false , para . binding ? . typeAlias ) ;
2023-05-16 06:28:30 +00:00
}
// call c function
2023-05-29 22:03:29 +00:00
if ( options . customizeCall )
fun . line ( options . customizeCall ) ;
else
fun . call ( api . name , api . params . map ( x => x . name ) , api . returnType === "void" ? null : { type : api . returnType , name : "returnVal" } ) ;
2023-05-16 06:28:30 +00:00
// clean up parameters
2023-06-04 20:31:15 +00:00
for ( let i = 0 ; i < activeParams . length ; i ++ ) {
const param = activeParams [ i ] ;
2023-06-03 07:15:38 +00:00
if ( param . binding ? . customCleanup )
2023-06-04 20:31:15 +00:00
param . binding . customCleanup ( fun , "argv[" + i + "]" ) ;
2023-06-04 11:41:18 +00:00
else
fun . jsCleanUpParameter ( param . type , param . name ) ;
2023-05-16 06:28:30 +00:00
}
// return result
if ( api . returnType === "void" ) {
2023-05-29 22:03:29 +00:00
if ( options . after )
options . after ( fun ) ;
2023-05-16 06:28:30 +00:00
fun . statement ( "return JS_UNDEFINED" ) ;
}
else {
fun . jsToJs ( api . returnType , "ret" , "returnVal" , this . structLookup ) ;
2023-05-29 22:03:29 +00:00
if ( options . after )
options . after ( fun ) ;
2023-05-16 06:28:30 +00:00
fun . returnExp ( "ret" ) ;
}
2023-05-08 14:43:50 +00:00
}
// add binding to function declaration
2023-06-02 16:58:53 +00:00
this . moduleFunctionList . jsFuncDef ( jName , ( api . params || [ ] ) . filter ( x => ! x . binding ? . ignore ) . length , fun . getTag ( "_name" ) ) ;
2023-05-14 20:19:47 +00:00
this . typings . addFunction ( jName , api ) ;
2023-05-06 21:43:40 +00:00
}
2023-06-02 09:52:33 +00:00
addEnum ( renum ) {
2023-06-02 16:58:53 +00:00
console . log ( "Binding enum " + renum . name ) ;
2023-06-13 21:03:38 +00:00
renum . values . forEach ( x => this . exportGlobalInt ( x . name , x . description ) ) ;
2023-05-06 21:43:40 +00:00
}
2023-06-02 09:52:33 +00:00
addApiStruct ( struct ) {
const options = struct . binding || { } ;
2023-06-02 16:58:53 +00:00
console . log ( "Binding struct " + struct . name ) ;
2023-05-14 20:19:47 +00:00
const classId = this . definitions . jsClassId ( ` js_ ${ struct . name } _class_id ` ) ;
2023-05-08 21:37:58 +00:00
this . registerStruct ( struct . name , classId ) ;
2023-06-02 09:52:33 +00:00
options . aliases ? . forEach ( x => this . registerStruct ( x , classId ) ) ;
const finalizer = this . structs . jsStructFinalizer ( classId , struct . name , ( gen , ptr ) => options . destructor && gen . call ( options . destructor . name , [ "*" + ptr ] ) ) ;
2023-05-08 16:05:03 +00:00
const propDeclarations = this . structs . createGenerator ( ) ;
if ( options && options . properties ) {
for ( const field of Object . keys ( options . properties ) ) {
const type = struct . fields . find ( x => x . name === field ) ? . type ;
if ( ! type )
throw new Error ( ` Struct ${ struct . name } does not contain field ${ field } ` ) ;
const el = options . properties [ field ] ;
let _get = undefined ;
let _set = undefined ;
if ( el . get )
2023-06-12 15:38:31 +00:00
_get = this . structs . jsStructGetter ( struct . name , classId , field , type , /*Be carefull when allocating memory in a getter*/ this . structLookup , el . overrideRead ) ;
2023-05-08 21:37:58 +00:00
if ( el . set )
2023-06-12 15:38:31 +00:00
_set = this . structs . jsStructSetter ( struct . name , classId , field , type , this . structLookup , el . overrideWrite ) ;
2023-05-08 21:37:58 +00:00
propDeclarations . jsGetSetDef ( field , _get ? . getTag ( "_name" ) , _set ? . getTag ( "_name" ) ) ;
2023-05-08 16:05:03 +00:00
}
}
2023-05-08 14:43:50 +00:00
const classFuncList = this . structs . jsFunctionList ( ` js_ ${ struct . name } _proto_funcs ` ) ;
2023-05-08 16:05:03 +00:00
classFuncList . child ( propDeclarations ) ;
2023-05-08 21:37:58 +00:00
classFuncList . jsPropStringDef ( "[Symbol.toStringTag]" , struct . name ) ;
2023-05-08 14:43:50 +00:00
const classDecl = this . structs . jsClassDeclaration ( struct . name , classId , finalizer . getTag ( "_name" ) , classFuncList . getTag ( "_name" ) ) ;
this . moduleInit . call ( classDecl . getTag ( "_name" ) , [ "ctx" , "m" ] ) ;
2023-05-20 19:34:27 +00:00
if ( options ? . createConstructor || options ? . createEmptyConstructor ) {
const body = this . functions . jsStructConstructor ( struct . name , options ? . createEmptyConstructor ? [ ] : struct . fields , classId , this . structLookup ) ;
2023-05-09 21:25:28 +00:00
this . moduleInit . statement ( ` JSValue ${ struct . name } _constr = JS_NewCFunction2(ctx, ${ body . getTag ( "_name" ) } ," ${ struct . name } )", ${ struct . fields . length } , JS_CFUNC_constructor_or_func, 0) ` ) ;
this . moduleInit . call ( "JS_SetModuleExport" , [ "ctx" , "m" , ` " ${ struct . name } " ` , struct . name + "_constr" ] ) ;
this . moduleEntry . call ( "JS_AddModuleExport" , [ "ctx" , "m" , '"' + struct . name + '"' ] ) ;
}
2023-06-02 16:58:53 +00:00
this . typings . addStruct ( struct ) ;
2023-05-06 21:43:40 +00:00
}
2023-05-14 20:19:47 +00:00
exportGlobalStruct ( structName , exportName , values , description ) {
2023-05-10 21:26:53 +00:00
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 } " ` ] ) ;
2023-05-14 20:19:47 +00:00
this . typings . constants . tsDeclareConstant ( exportName , structName , description ) ;
2023-05-10 21:26:53 +00:00
}
2023-06-13 21:03:38 +00:00
exportGlobalInt ( name , description ) {
2023-05-11 18:54:49 +00:00
this . moduleInit . statement ( ` JS_SetModuleExport(ctx, m, " ${ name } ", JS_NewInt32(ctx, ${ name } )) ` ) ;
this . moduleEntry . statement ( ` JS_AddModuleExport(ctx, m, " ${ name } ") ` ) ;
2023-05-14 20:19:47 +00:00
this . typings . constants . tsDeclareConstant ( name , "number" , description ) ;
2023-05-11 18:54:49 +00:00
}
2023-06-13 21:03:38 +00:00
exportGlobalDouble ( name , description ) {
this . moduleInit . statement ( ` JS_SetModuleExport(ctx, m, " ${ name } ", JS_NewFloat64(ctx, ${ name } )) ` ) ;
this . moduleEntry . statement ( ` JS_AddModuleExport(ctx, m, " ${ name } ") ` ) ;
this . typings . constants . tsDeclareConstant ( name , "number" , description ) ;
}
2023-05-06 21:43:40 +00:00
}
2023-05-08 14:43:50 +00:00
exports . RayLibHeader = RayLibHeader ;
2023-05-06 21:43:40 +00:00
2023-05-14 20:19:47 +00:00
/***/ } ) ,
/***/ "./src/typescript.ts" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / typescript . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( _ _unused _webpack _module , exports , _ _webpack _require _ _ ) => {
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
exports . TypescriptGenerator = exports . GenericTypescriptGenerator = exports . TypeScriptDeclaration = void 0 ;
const generation _1 = _ _webpack _require _ _ ( /*! ./generation */ "./src/generation.ts" ) ;
const fs _1 = _ _webpack _require _ _ ( /*! fs */ "fs" ) ;
class TypeScriptDeclaration {
constructor ( ) {
this . root = new TypescriptGenerator ( ) ;
this . structs = this . root . child ( ) ;
this . functions = this . root . child ( ) ;
this . constants = this . root . child ( ) ;
}
addFunction ( name , api ) {
2023-06-02 16:58:53 +00:00
const options = api . binding || { } ;
2023-06-03 07:15:38 +00:00
const para = ( api . params || [ ] ) . filter ( x => ! x . binding ? . ignore ) . map ( x => ( { name : x . name , type : x . binding ? . jsType ? ? this . toJsType ( x . type ) } ) ) ;
2023-06-02 16:58:53 +00:00
const returnType = options . jsReturns ? ? this . toJsType ( api . returnType ) ;
2023-05-14 20:19:47 +00:00
this . functions . tsDeclareFunction ( name , para , returnType , api . description ) ;
}
2023-06-02 16:58:53 +00:00
addStruct ( api ) {
const options = api . binding || { } ;
2023-05-14 20:19:47 +00:00
var fields = api . fields . filter ( x => ! ! ( options . properties || { } ) [ x . name ] ) . map ( x => ( { name : x . name , description : x . description , type : this . toJsType ( x . type ) } ) ) ;
this . structs . tsDeclareInterface ( api . name , fields ) ;
2023-05-20 19:34:27 +00:00
this . structs . tsDeclareType ( api . name , ! ! ( options . createConstructor || options . createEmptyConstructor ) , options . createEmptyConstructor ? [ ] : fields ) ;
2023-05-14 20:19:47 +00:00
}
toJsType ( type ) {
switch ( type ) {
case "int" :
case "long" :
case "unsigned int" :
case "unsigned char" :
case "float" :
case "double" :
return "number" ;
2023-05-24 20:47:17 +00:00
case "const unsigned char *" :
2023-05-20 19:34:27 +00:00
case "unsigned char *" :
case "unsigned short *" :
case "float *" :
return "ArrayBuffer" ;
2023-05-14 20:19:47 +00:00
case "bool" :
return "boolean" ;
case "const char *" :
case "char *" :
2023-06-06 14:50:38 +00:00
return "string | undefined | null" ;
2023-05-16 06:28:30 +00:00
case "void *" :
case "const void *" :
return "any" ;
case "Camera" :
2023-05-20 19:34:27 +00:00
case "Camera *" :
2023-05-16 06:28:30 +00:00
return "Camera3D" ;
case "Texture2D" :
2023-05-20 19:34:27 +00:00
case "Texture2D *" :
2023-05-16 06:28:30 +00:00
case "TextureCubemap" :
return "Texture" ;
2023-05-20 19:34:27 +00:00
case "RenderTexture2D" :
case "RenderTexture2D *" :
return "RenderTexture" ;
2023-05-16 06:28:30 +00:00
case "Quaternion" :
return "Vector4" ;
2023-05-14 20:19:47 +00:00
default :
2023-05-20 19:34:27 +00:00
return type . replace ( " *" , "" ) . replace ( "const " , "" ) ;
2023-05-14 20:19:47 +00:00
}
}
writeTo ( filename ) {
const writer = new generation _1 . CodeWriter ( ) ;
writer . writeGenerator ( this . root ) ;
( 0 , fs _1 . writeFileSync ) ( filename , writer . toString ( ) ) ;
}
}
exports . TypeScriptDeclaration = TypeScriptDeclaration ;
class GenericTypescriptGenerator extends generation _1 . GenericCodeGenerator {
tsDeclareFunction ( name , parameters , returnType , description ) {
this . tsDocComment ( description ) ;
this . statement ( ` declare function ${ name } ( ${ parameters . map ( x => x . name + ': ' + x . type ) . join ( ', ' ) } ): ${ returnType } ` ) ;
}
tsDeclareConstant ( name , type , description ) {
this . tsDocComment ( description ) ;
this . statement ( ` declare var ${ name } : ${ type } ` ) ;
}
tsDeclareType ( name , hasConstructor , parameters ) {
this . line ( ` declare var ${ name } : { ` ) ;
this . indent ( ) ;
this . statement ( "prototype: " + name ) ;
if ( hasConstructor )
this . statement ( ` new( ${ parameters . map ( x => x . name + ": " + x . type ) . join ( ', ' ) } ): ${ name } ` ) ;
this . unindent ( ) ;
this . line ( "}" ) ;
}
tsDeclareInterface ( name , fields ) {
this . line ( ` interface ${ name } { ` ) ;
this . indent ( ) ;
for ( const field of fields ) {
if ( field . description )
this . tsDocComment ( field . description ) ;
this . line ( field . name + ": " + field . type + "," ) ;
}
this . unindent ( ) ;
this . line ( "}" ) ;
}
tsDocComment ( comment ) {
this . line ( ` /** ${ comment } */ ` ) ;
}
}
exports . GenericTypescriptGenerator = GenericTypescriptGenerator ;
class TypescriptGenerator extends GenericTypescriptGenerator {
createGenerator ( ) {
return new TypescriptGenerator ( ) ;
}
}
exports . TypescriptGenerator = TypescriptGenerator ;
2023-05-06 21:43:40 +00:00
/***/ } ) ,
/***/ "fs" :
/ * ! * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * external "fs" * * * !
\ * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module ) => {
module . exports = require ( "fs" ) ;
/***/ } )
/******/ } ) ;
/************************************************************************/
/******/ // The module cache
/******/ var _ _webpack _module _cache _ _ = { } ;
/******/
/******/ // The require function
/******/ function _ _webpack _require _ _ ( moduleId ) {
/******/ // Check if module is in cache
/******/ var cachedModule = _ _webpack _module _cache _ _ [ moduleId ] ;
/******/ if ( cachedModule !== undefined ) {
/******/ return cachedModule . exports ;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = _ _webpack _module _cache _ _ [ moduleId ] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports : { }
/******/ } ;
/******/
/******/ // Execute the module function
/******/ _ _webpack _modules _ _ [ moduleId ] ( module , module . exports , _ _webpack _require _ _ ) ;
/******/
/******/ // Return the exports of the module
/******/ return module . exports ;
/******/ }
/******/
/************************************************************************/
var _ _webpack _exports _ _ = { } ;
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
( ( ) => {
var exports = _ _webpack _exports _ _ ;
/ * ! * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . / src / index . ts * * * !
\ * * * * * * * * * * * * * * * * * * * * * * /
Object . defineProperty ( exports , "__esModule" , ( { value : true } ) ) ;
const fs _1 = _ _webpack _require _ _ ( /*! fs */ "fs" ) ;
2023-05-08 14:43:50 +00:00
const raylib _header _1 = _ _webpack _require _ _ ( /*! ./raylib-header */ "./src/raylib-header.ts" ) ;
2023-05-26 20:09:53 +00:00
const header _parser _1 = _ _webpack _require _ _ ( /*! ./header-parser */ "./src/header-parser.ts" ) ;
2023-06-02 16:58:53 +00:00
let api ;
2023-06-02 09:52:33 +00:00
function getFunction ( funList , name ) {
return funList . find ( x => x . name === name ) ;
}
function getStruct ( strList , name ) {
return strList . find ( x => x . name === name ) ;
}
function getAliases ( aliasList , name ) {
return aliasList . filter ( x => x . type === name ) . map ( x => x . name ) ;
}
2023-06-02 16:58:53 +00:00
function ignore ( name ) {
getFunction ( api . functions , name ) . binding = { ignore : true } ;
}
2023-05-06 21:43:40 +00:00
function main ( ) {
2023-05-25 05:57:23 +00:00
// Load the pre-generated raylib api
2023-06-02 16:58:53 +00:00
api = JSON . parse ( ( 0 , fs _1 . readFileSync ) ( "thirdparty/raylib/parser/output/raylib_api.json" , 'utf8' ) ) ;
2023-05-26 20:09:53 +00:00
const parser = new header _parser _1 . HeaderParser ( ) ;
const rmathHeader = ( 0 , fs _1 . readFileSync ) ( "thirdparty/raylib/src/raymath.h" , "utf8" ) ;
2023-05-26 22:47:44 +00:00
const mathApi = parser . parseFunctions ( rmathHeader ) ;
2023-05-15 15:44:28 +00:00
mathApi . forEach ( x => api . functions . push ( x ) ) ;
2023-05-26 20:09:53 +00:00
const rcameraHeader = ( 0 , fs _1 . readFileSync ) ( "thirdparty/raylib/src/rcamera.h" , "utf8" ) ;
2023-05-26 22:47:44 +00:00
const cameraApi = parser . parseFunctionDefinitions ( rcameraHeader ) ;
2023-05-26 06:10:27 +00:00
cameraApi . forEach ( x => api . functions . push ( x ) ) ;
2023-06-02 06:03:36 +00:00
const rguiHeader = ( 0 , fs _1 . readFileSync ) ( "thirdparty/raygui/src/raygui.h" , "utf8" ) ;
2023-05-26 22:47:44 +00:00
const rguiFunctions = parser . parseFunctionDefinitions ( rguiHeader ) ;
2023-06-02 06:03:36 +00:00
const rguiEnums = parser . parseEnums ( rguiHeader ) ;
2023-05-26 22:47:44 +00:00
//rguiApi.forEach(x => console.log(`core.addApiFunctionByName("${x.name}")`))
rguiFunctions . forEach ( x => api . functions . push ( x ) ) ;
2023-06-02 06:03:36 +00:00
rguiEnums . forEach ( x => api . enums . push ( x ) ) ;
const rlightsHeader = ( 0 , fs _1 . readFileSync ) ( "include/rlights.h" , "utf8" ) ;
2023-05-26 22:47:44 +00:00
const rlightsFunctions = parser . parseFunctions ( rlightsHeader , true ) ;
api . functions . push ( rlightsFunctions [ 0 ] ) ;
api . functions . push ( rlightsFunctions [ 1 ] ) ;
2023-06-11 10:49:26 +00:00
const rlightsEnums = parser . parseEnums ( rlightsHeader ) ;
rlightsEnums . forEach ( x => api . enums . push ( x ) ) ;
const rlightsStructs = parser . parseStructs ( rlightsHeader ) ;
rlightsStructs [ 0 ] . binding = {
properties : {
type : { get : true , set : true } ,
enabled : { get : true , set : true } ,
position : { get : true , set : true } ,
target : { get : true , set : true } ,
color : { get : true , set : true } ,
attenuation : { get : true , set : true } ,
} ,
} ;
api . structs . push ( rlightsStructs [ 0 ] ) ;
2023-06-02 06:03:36 +00:00
const reasingsHeader = ( 0 , fs _1 . readFileSync ) ( "include/reasings.h" , "utf8" ) ;
2023-05-26 22:47:44 +00:00
const reasingsFunctions = parser . parseFunctions ( reasingsHeader ) ;
reasingsFunctions . forEach ( x => api . functions . push ( x ) ) ;
2023-06-02 09:52:33 +00:00
// Custom Rayjs functions
api . functions . push ( {
name : "SetModelMaterial" ,
description : "Replace material in slot materialIndex" ,
returnType : "void" ,
params : [ { type : "Model *" , name : "model" } , { type : "int" , name : "materialIndex" } , { type : "Material" , name : "material" } ]
} ) ;
2023-06-11 10:49:26 +00:00
api . functions . push ( {
name : "SetShaderLocation" ,
description : "Set shader constant in shader locations array" ,
returnType : "void" ,
params : [ { type : "Shader *" , name : "shader" } , { type : "int" , name : "shaderConstant" } , { type : "int" , name : "location" } ]
} ) ;
2023-06-13 21:03:38 +00:00
api . functions . push ( {
name : "ImageReadPixel" ,
description : "Read a single pixel from an image" ,
returnType : "Color" ,
params : [ { type : "Image *" , name : "image" } , { type : "int" , name : "x" } , { type : "int" , name : "y" } ]
} ) ;
2023-06-02 09:52:33 +00:00
// Define a new header
const core = new raylib _header _1 . RayLibHeader ( "raylib_core" ) ;
2023-05-26 06:10:27 +00:00
core . includes . include ( "raymath.h" ) ;
core . includes . include ( "rcamera.h" ) ;
2023-05-26 22:47:44 +00:00
core . includes . line ( "#define RAYGUI_IMPLEMENTATION" ) ;
core . includes . include ( "raygui.h" ) ;
core . includes . line ( "#define RLIGHTS_IMPLEMENTATION" ) ;
core . includes . include ( "rlights.h" ) ;
core . includes . include ( "reasings.h" ) ;
2023-06-02 09:52:33 +00:00
getStruct ( api . structs , "Color" ) . binding = {
2023-05-08 21:37:58 +00:00
properties : {
r : { get : true , set : true } ,
g : { get : true , set : true } ,
b : { get : true , set : true } ,
a : { get : true , set : true } ,
2023-05-09 21:25:28 +00:00
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Rectangle" ) . binding = {
2023-05-11 20:10:40 +00:00
properties : {
x : { get : true , set : true } ,
y : { get : true , set : true } ,
width : { get : true , set : true } ,
height : { get : true , set : true } ,
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Vector2" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
x : { get : true , set : true } ,
y : { get : true , set : true } ,
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Vector3" ) . binding = {
2023-05-10 21:26:53 +00:00
properties : {
x : { get : true , set : true } ,
y : { get : true , set : true } ,
2023-05-14 20:19:47 +00:00
z : { get : true , set : true } ,
2023-05-10 21:26:53 +00:00
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Vector4" ) . binding = {
2023-05-13 12:49:05 +00:00
properties : {
x : { get : true , set : true } ,
y : { get : true , set : true } ,
z : { get : true , set : true } ,
2023-05-14 20:19:47 +00:00
w : { get : true , set : true } ,
2023-05-13 12:49:05 +00:00
} ,
2023-06-02 09:52:33 +00:00
createConstructor : true ,
aliases : getAliases ( api . aliases , "Vector4" )
} ;
getStruct ( api . structs , "Ray" ) . binding = {
2023-05-13 12:49:05 +00:00
properties : {
position : { get : false , set : true } ,
direction : { get : false , set : true } ,
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "RayCollision" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
hit : { get : true , set : false } ,
distance : { get : true , set : false } ,
2023-05-24 20:47:17 +00:00
point : { get : true , set : false } ,
normal : { get : true , set : false } ,
2023-05-14 20:19:47 +00:00
} ,
createConstructor : false
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Camera2D" ) . binding = {
2023-05-13 12:49:05 +00:00
properties : {
2023-05-24 20:47:17 +00:00
offset : { get : true , set : true } ,
target : { get : true , set : true } ,
2023-05-13 12:49:05 +00:00
rotation : { get : true , set : true } ,
zoom : { get : true , set : true } ,
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Camera3D" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
2023-05-16 06:28:30 +00:00
position : { get : true , set : true } ,
target : { get : true , set : true } ,
2023-05-14 20:19:47 +00:00
up : { get : false , set : true } ,
fovy : { get : true , set : true } ,
projection : { get : true , set : true } ,
} ,
2023-06-02 09:52:33 +00:00
createConstructor : true ,
aliases : getAliases ( api . aliases , "Camera3D" )
} ;
getStruct ( api . structs , "BoundingBox" ) . binding = {
2023-05-24 20:47:17 +00:00
properties : {
min : { get : true , set : true } ,
max : { get : true , set : true } ,
} ,
2023-05-14 20:19:47 +00:00
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Matrix" ) . binding = {
2023-05-13 12:49:05 +00:00
properties : { } ,
createConstructor : false
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "NPatchInfo" ) . binding = {
2023-05-20 19:34:27 +00:00
properties : {
source : { get : true , set : true } ,
left : { get : true , set : true } ,
top : { get : true , set : true } ,
right : { get : true , set : true } ,
bottom : { get : true , set : true } ,
layout : { get : true , set : true } ,
} ,
createConstructor : true
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Image" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
2023-05-24 20:47:17 +00:00
//data: { set: true },
2023-05-14 20:19:47 +00:00
width : { get : true } ,
height : { get : true } ,
mipmaps : { get : true } ,
format : { get : true }
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadImage"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Wave" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
frameCount : { get : true } ,
sampleRate : { get : true } ,
sampleSize : { get : true } ,
channels : { get : true }
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadWave"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Sound" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
frameCount : { get : true }
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadSound"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Music" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
frameCount : { get : true } ,
2023-05-24 20:47:17 +00:00
looping : { get : true , set : true } ,
ctxType : { get : true } ,
2023-05-14 20:19:47 +00:00
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadMusicStream"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Model" ) . binding = {
2023-05-24 20:47:17 +00:00
properties : {
transform : { get : true , set : true } ,
meshCount : { get : true } ,
materialCount : { get : true } ,
boneCount : { get : true } ,
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadModel"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Mesh" ) . binding = {
2023-05-20 19:34:27 +00:00
properties : {
vertexCount : { get : true , set : true } ,
triangleCount : { get : true , set : true } ,
// TODO: Free previous pointers before overwriting
vertices : { set : true } ,
texcoords : { set : true } ,
texcoords2 : { set : true } ,
normals : { set : true } ,
tangents : { set : true } ,
colors : { set : true } ,
indices : { set : true } ,
animVertices : { set : true } ,
animNormals : { set : true } ,
boneIds : { set : true } ,
boneWeights : { set : true } ,
} ,
createEmptyConstructor : true
//destructor: "UnloadMesh"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Shader" ) . binding = {
2023-05-24 20:47:17 +00:00
properties : {
id : { get : true }
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadShader"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Texture" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
width : { get : true } ,
2023-05-24 20:47:17 +00:00
height : { get : true } ,
mipmaps : { get : true } ,
format : { get : true } ,
2023-05-14 20:19:47 +00:00
} ,
2023-06-02 09:52:33 +00:00
aliases : getAliases ( api . aliases , "Texture" )
2023-05-20 19:34:27 +00:00
//destructor: "UnloadTexture"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Font" ) . binding = {
2023-05-14 20:19:47 +00:00
properties : {
2023-05-24 20:47:17 +00:00
baseSize : { get : true } ,
glyphCount : { get : true } ,
glyphPadding : { get : true } ,
2023-05-14 20:19:47 +00:00
} ,
2023-05-20 19:34:27 +00:00
//destructor: "UnloadFont"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "RenderTexture" ) . binding = {
2023-05-24 20:47:17 +00:00
properties : {
id : { get : true }
} ,
2023-06-02 09:52:33 +00:00
aliases : getAliases ( api . aliases , "RenderTexture" )
2023-05-20 19:34:27 +00:00
//destructor: "UnloadRenderTexture"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "MaterialMap" ) . binding = {
2023-05-20 19:34:27 +00:00
properties : {
texture : { set : true } ,
color : { set : true , get : true } ,
value : { get : true , set : true }
} ,
//destructor: "UnloadMaterialMap"
2023-06-02 09:52:33 +00:00
} ;
getStruct ( api . structs , "Material" ) . binding = {
2023-05-20 19:34:27 +00:00
properties : {
shader : { set : true }
} ,
//destructor: "UnloadMaterial"
2023-06-02 09:52:33 +00:00
} ;
2023-06-12 15:38:31 +00:00
const structDI = getStruct ( api . structs , "VrDeviceInfo" ) ;
structDI . fields . filter ( x => x . name === "lensDistortionValues" ) [ 0 ] . type = "Vector4" ;
structDI . binding = {
createEmptyConstructor : true ,
properties : {
hResolution : { set : true , get : true } ,
vResolution : { set : true , get : true } ,
hScreenSize : { set : true , get : true } ,
vScreenSize : { set : true , get : true } ,
vScreenCenter : { set : true , get : true } ,
eyeToScreenDistance : { set : true , get : true } ,
lensSeparationDistance : { set : true , get : true } ,
interpupillaryDistance : { set : true , get : true } ,
// lensDistortionValues: {
// set: true,
// get: true,
// overrideRead(fn) {
// fn.line("// TODO")
// },
// overrideWrite(fn) {
// fn.line("// TODO")
// },
// },
}
} ;
2023-06-05 20:03:08 +00:00
getFunction ( api . functions , "EndDrawing" ) . binding = { after : gen => gen . call ( "app_update_quickjs" , [ ] ) } ;
2023-06-02 16:58:53 +00:00
ignore ( "SetWindowIcons" ) ;
ignore ( "GetWindowHandle" ) ;
2023-05-13 12:49:05 +00:00
// Custom frame control functions
// NOT SUPPORTED BECAUSE NEEDS COMPILER FLAG
2023-06-02 16:58:53 +00:00
ignore ( "SwapScreenBuffer" ) ;
ignore ( "PollInputEvents" ) ;
ignore ( "WaitTime" ) ;
2023-06-12 15:38:31 +00:00
//ignore("BeginVrStereoMode")
//ignore("EndVrStereoMode")
//ignore("LoadVrStereoConfig")
//ignore("UnloadVrStereoConfig")
2023-06-02 09:52:33 +00:00
getFunction ( api . functions , "SetShaderValue" ) . binding = { body : ( gen ) => {
2023-05-16 06:28:30 +00:00
gen . jsToC ( "Shader" , "shader" , "argv[0]" , core . structLookup ) ;
gen . jsToC ( "int" , "locIndex" , "argv[1]" , core . structLookup ) ;
gen . declare ( "value" , "void *" , false , "NULL" ) ;
2023-05-16 09:59:29 +00:00
gen . declare ( "valueFloat" , "float" ) ;
gen . declare ( "valueInt" , "int" ) ;
2023-05-16 06:28:30 +00:00
gen . jsToC ( "int" , "uniformType" , "argv[3]" , core . structLookup ) ;
const sw = gen . switch ( "uniformType" ) ;
let b = sw . caseBreak ( "SHADER_UNIFORM_FLOAT" ) ;
2023-05-16 09:59:29 +00:00
b . jsToC ( "float" , "valueFloat" , "argv[2]" , core . structLookup , true ) ;
2023-05-16 06:28:30 +00:00
b . statement ( "value = (void *)&valueFloat" ) ;
b = sw . caseBreak ( "SHADER_UNIFORM_VEC2" ) ;
b . jsToC ( "Vector2 *" , "valueV2" , "argv[2]" , core . structLookup ) ;
b . statement ( "value = (void*)valueV2" ) ;
b = sw . caseBreak ( "SHADER_UNIFORM_VEC3" ) ;
b . jsToC ( "Vector3 *" , "valueV3" , "argv[2]" , core . structLookup ) ;
b . statement ( "value = (void*)valueV3" ) ;
b = sw . caseBreak ( "SHADER_UNIFORM_VEC4" ) ;
b . jsToC ( "Vector4 *" , "valueV4" , "argv[2]" , core . structLookup ) ;
b . statement ( "value = (void*)valueV4" ) ;
b = sw . caseBreak ( "SHADER_UNIFORM_INT" ) ;
2023-05-16 09:59:29 +00:00
b . jsToC ( "int" , "valueInt" , "argv[2]" , core . structLookup , true ) ;
2023-05-16 06:28:30 +00:00
b . statement ( "value = (void*)&valueInt" ) ;
b = sw . defaultBreak ( ) ;
b . returnExp ( "JS_EXCEPTION" ) ;
gen . call ( "SetShaderValue" , [ "shader" , "locIndex" , "value" , "uniformType" ] ) ;
gen . returnExp ( "JS_UNDEFINED" ) ;
2023-06-02 09:52:33 +00:00
} } ;
2023-06-02 16:58:53 +00:00
ignore ( "SetShaderValueV" ) ;
const traceLog = getFunction ( api . functions , "TraceLog" ) ;
traceLog . params ? . pop ( ) ;
// Memory functions not supported on JS, just use ArrayBuffer
ignore ( "MemAlloc" ) ;
ignore ( "MemRealloc" ) ;
ignore ( "MemFree" ) ;
2023-05-13 12:49:05 +00:00
// Callbacks not supported on JS
2023-06-02 16:58:53 +00:00
ignore ( "SetTraceLogCallback" ) ;
ignore ( "SetLoadFileDataCallback" ) ;
ignore ( "SetSaveFileDataCallback" ) ;
ignore ( "SetLoadFileTextCallback" ) ;
ignore ( "SetSaveFileTextCallback" ) ;
2023-05-13 12:49:05 +00:00
// Files management functions
2023-06-02 16:58:53 +00:00
const lfd = getFunction ( api . functions , "LoadFileData" ) ;
lfd . params [ lfd . params . length - 1 ] . binding = { ignore : true } ;
lfd . binding = {
body : gen => {
2023-05-24 20:47:17 +00:00
gen . jsToC ( "const char *" , "fileName" , "argv[0]" ) ;
gen . declare ( "bytesRead" , "unsigned int" ) ;
gen . call ( "LoadFileData" , [ "fileName" , "&bytesRead" ] , { type : "unsigned char *" , name : "retVal" } ) ;
gen . statement ( "JSValue buffer = JS_NewArrayBufferCopy(ctx, (const uint8_t*)retVal, bytesRead)" ) ;
gen . call ( "UnloadFileData" , [ "retVal" ] ) ;
gen . jsCleanUpParameter ( "const char*" , "fileName" ) ;
gen . returnExp ( "buffer" ) ;
2023-06-02 16:58:53 +00:00
}
} ;
ignore ( "UnloadFileData" ) ;
// TODO: SaveFileData works but unnecessary makes copy of memory
getFunction ( api . functions , "SaveFileData" ) . binding = { } ;
ignore ( "ExportDataAsCode" ) ;
getFunction ( api . functions , "LoadFileText" ) . binding = { after : gen => gen . call ( "UnloadFileText" , [ "returnVal" ] ) } ;
2023-06-03 07:15:38 +00:00
getFunction ( api . functions , "SaveFileText" ) . params [ 1 ] . binding = { typeAlias : "const char *" } ;
2023-06-02 16:58:53 +00:00
ignore ( "UnloadFileText" ) ;
const createFileList = ( gen , loadName , unloadName , args ) => {
gen . call ( loadName , args , { type : "FilePathList" , name : "files" } ) ;
gen . call ( "JS_NewArray" , [ "ctx" ] , { type : "JSValue" , name : "ret" } ) ;
const f = gen . for ( "i" , "files.count" ) ;
f . call ( "JS_SetPropertyUint32" , [ "ctx" , "ret" , "i" , "JS_NewString(ctx,files.paths[i])" ] ) ;
gen . call ( unloadName , [ "files" ] ) ;
} ;
getFunction ( api . functions , "LoadDirectoryFiles" ) . binding = {
jsReturns : "string[]" ,
2023-06-02 06:03:36 +00:00
body : gen => {
2023-06-02 16:58:53 +00:00
gen . jsToC ( "const char *" , "dirPath" , "argv[0]" ) ;
createFileList ( gen , "LoadDirectoryFiles" , "UnloadDirectoryFiles" , [ "dirPath" ] ) ;
gen . jsCleanUpParameter ( "const char *" , "dirPath" ) ;
2023-06-02 06:03:36 +00:00
gen . returnExp ( "ret" ) ;
}
2023-06-02 16:58:53 +00:00
} ;
getFunction ( api . functions , "LoadDirectoryFilesEx" ) . binding = {
jsReturns : "string[]" ,
body : gen => {
gen . jsToC ( "const char *" , "basePath" , "argv[0]" ) ;
gen . jsToC ( "const char *" , "filter" , "argv[1]" ) ;
gen . jsToC ( "bool" , "scanSubdirs" , "argv[2]" ) ;
createFileList ( gen , "LoadDirectoryFilesEx" , "UnloadDirectoryFiles" , [ "basePath" , "filter" , "scanSubdirs" ] ) ;
gen . jsCleanUpParameter ( "const char *" , "basePath" ) ;
gen . jsCleanUpParameter ( "const char *" , "filter" ) ;
gen . returnExp ( "ret" ) ;
}
} ;
ignore ( "UnloadDirectoryFiles" ) ;
getFunction ( api . functions , "LoadDroppedFiles" ) . binding = {
jsReturns : "string[]" ,
body : gen => {
createFileList ( gen , "LoadDroppedFiles" , "UnloadDroppedFiles" , [ ] ) ;
gen . returnExp ( "ret" ) ;
}
} ;
ignore ( "UnloadDroppedFiles" ) ;
2023-05-24 20:47:17 +00:00
// Compression/encoding functionality
2023-06-02 16:58:53 +00:00
ignore ( "CompressData" ) ;
ignore ( "DecompressData" ) ;
ignore ( "EncodeDataBase64" ) ;
ignore ( "DecodeDataBase64" ) ;
ignore ( "DrawLineStrip" ) ;
ignore ( "DrawTriangleFan" ) ;
ignore ( "DrawTriangleStrip" ) ;
ignore ( "CheckCollisionPointPoly" ) ;
ignore ( "CheckCollisionLines" ) ;
ignore ( "LoadImageAnim" ) ;
ignore ( "ExportImageAsCode" ) ;
getFunction ( api . functions , "LoadImageColors" ) . binding = {
jsReturns : "ArrayBuffer" ,
body : gen => {
2023-05-20 19:34:27 +00:00
gen . jsToC ( "Image" , "image" , "argv[0]" , core . structLookup ) ;
gen . call ( "LoadImageColors" , [ "image" ] , { name : "colors" , type : "Color *" } ) ;
gen . statement ( "JSValue retVal = JS_NewArrayBufferCopy(ctx, (const uint8_t*)colors, image.width*image.height*sizeof(Color))" ) ;
gen . call ( "UnloadImageColors" , [ "colors" ] ) ;
gen . returnExp ( "retVal" ) ;
2023-06-02 16:58:53 +00:00
}
} ;
ignore ( "LoadImagePalette" ) ;
ignore ( "UnloadImageColors" ) ;
ignore ( "UnloadImagePalette" ) ;
ignore ( "GetPixelColor" ) ;
ignore ( "SetPixelColor" ) ;
const lfx = getFunction ( api . functions , "LoadFontEx" ) ;
lfx . params [ 2 ] . binding = { ignore : true } ;
lfx . params [ 3 ] . binding = { ignore : true } ;
lfx . binding = { customizeCall : "Font returnVal = LoadFontEx(fileName, fontSize, NULL, 0);" } ;
ignore ( "LoadFontFromMemory" ) ;
ignore ( "LoadFontData" ) ;
ignore ( "GenImageFontAtlas" ) ;
ignore ( "UnloadFontData" ) ;
ignore ( "ExportFontAsCode" ) ;
ignore ( "DrawTextCodepoints" ) ;
ignore ( "GetGlyphInfo" ) ;
ignore ( "LoadUTF8" ) ;
ignore ( "UnloadUTF8" ) ;
ignore ( "LoadCodepoints" ) ;
ignore ( "UnloadCodepoints" ) ;
ignore ( "GetCodepointCount" ) ;
ignore ( "GetCodepoint" ) ;
ignore ( "GetCodepointNext" ) ;
ignore ( "GetCodepointPrevious" ) ;
ignore ( "CodepointToUTF8" ) ;
2023-05-15 21:02:41 +00:00
// Not supported, use JS Stdlib instead
2023-06-02 16:58:53 +00:00
api . functions . filter ( x => x . name . startsWith ( "Text" ) ) . forEach ( x => ignore ( x . name ) ) ;
ignore ( "DrawTriangleStrip3D" ) ;
ignore ( "LoadMaterials" ) ;
ignore ( "LoadModelAnimations" ) ;
ignore ( "UpdateModelAnimation" ) ;
ignore ( "UnloadModelAnimation" ) ;
ignore ( "UnloadModelAnimations" ) ;
ignore ( "IsModelAnimationValid" ) ;
ignore ( "ExportWaveAsCode" ) ;
2023-05-14 20:19:47 +00:00
// Wave/Sound management functions
2023-06-02 16:58:53 +00:00
ignore ( "LoadWaveSamples" ) ;
ignore ( "UnloadWaveSamples" ) ;
ignore ( "LoadMusicStreamFromMemory" ) ;
ignore ( "LoadAudioStream" ) ;
ignore ( "IsAudioStreamReady" ) ;
ignore ( "UnloadAudioStream" ) ;
ignore ( "UpdateAudioStream" ) ;
ignore ( "IsAudioStreamProcessed" ) ;
ignore ( "PlayAudioStream" ) ;
ignore ( "PauseAudioStream" ) ;
ignore ( "ResumeAudioStream" ) ;
ignore ( "IsAudioStreamPlaying" ) ;
ignore ( "StopAudioStream" ) ;
ignore ( "SetAudioStreamVolume" ) ;
ignore ( "SetAudioStreamPitch" ) ;
ignore ( "SetAudioStreamPan" ) ;
ignore ( "SetAudioStreamBufferSizeDefault" ) ;
ignore ( "SetAudioStreamCallback" ) ;
ignore ( "AttachAudioStreamProcessor" ) ;
ignore ( "DetachAudioStreamProcessor" ) ;
ignore ( "AttachAudioMixedProcessor" ) ;
ignore ( "DetachAudioMixedProcessor" ) ;
ignore ( "Vector3OrthoNormalize" ) ;
ignore ( "Vector3ToFloatV" ) ;
ignore ( "MatrixToFloatV" ) ;
ignore ( "QuaternionToAxisAngle" ) ;
2023-06-13 21:03:38 +00:00
core . exportGlobalDouble ( "DEG2RAD" , "(PI/180.0)" ) ;
core . exportGlobalDouble ( "RAD2DEG" , "(180.0/PI)" ) ;
2023-06-03 07:15:38 +00:00
const setOutParam = ( fun , index ) => {
const param = fun . params [ index ] ;
param . binding = {
jsType : ` { ${ param . name } : number } ` ,
2023-06-04 20:31:15 +00:00
customConverter : ( gen , src ) => {
gen . declare ( param . name , param . type , false , "NULL" ) ;
2023-06-03 07:15:38 +00:00
gen . declare ( param . name + "_out" , param . type . replace ( " *" , "" ) ) ;
2023-06-04 20:31:15 +00:00
const body = gen . if ( "!JS_IsNull(" + src + ")" ) ;
body . statement ( param . name + " = &" + param . name + "_out" ) ;
body . call ( "JS_GetPropertyStr" , [ "ctx" , src , '"' + param . name + '"' ] , { name : param . name + "_js" , type : "JSValue" } ) ;
body . call ( "JS_ToInt32" , [ "ctx" , param . name , param . name + "_js" ] ) ;
2023-06-03 07:15:38 +00:00
} ,
2023-06-04 20:31:15 +00:00
customCleanup : ( gen , src ) => {
const body = gen . if ( "!JS_IsNull(" + src + ")" ) ;
body . call ( "JS_SetPropertyStr" , [ "ctx" , src , ` " ${ param . name } " ` , "JS_NewInt32(ctx," + param . name + "_out)" ] ) ;
2023-06-03 07:15:38 +00:00
}
} ;
} ;
2023-06-04 11:41:18 +00:00
const setOutParamString = ( fun , index , indexLen ) => {
const lenParam = fun . params [ indexLen ] ;
lenParam . binding = { ignore : true } ;
const param = fun . params [ index ] ;
param . binding = {
jsType : ` { ${ param . name } : string } ` ,
2023-06-04 20:31:15 +00:00
customConverter : ( gen , src ) => {
gen . call ( "JS_GetPropertyStr" , [ "ctx" , src , '"' + param . name + '"' ] , { name : param . name + "_js" , type : "JSValue" } ) ;
2023-06-04 11:41:18 +00:00
gen . declare ( param . name + "_len" , "size_t" ) ;
gen . call ( "JS_ToCStringLen" , [ "ctx" , "&" + param . name + "_len" , param . name + "_js" ] , { name : param . name + "_val" , type : "const char *" } ) ;
gen . call ( "memcpy" , [ "(void *)textbuffer" , param . name + "_val" , param . name + "_len" ] ) ;
gen . statement ( "textbuffer[" + param . name + "_len] = 0" ) ;
gen . declare ( param . name , param . type , false , "textbuffer" ) ;
gen . declare ( lenParam . name , lenParam . type , false , "4096" ) ;
} ,
2023-06-04 20:31:15 +00:00
customCleanup : ( gen , src ) => {
2023-06-04 11:41:18 +00:00
gen . jsCleanUpParameter ( "const char *" , param . name + "_val" ) ;
2023-06-04 20:31:15 +00:00
gen . call ( "JS_SetPropertyStr" , [ "ctx" , src , ` " ${ param . name } " ` , "JS_NewString(ctx," + param . name + ")" ] ) ;
2023-06-04 11:41:18 +00:00
}
} ;
} ;
core . definitions . declare ( "textbuffer[4096]" , "char" , true ) ;
2023-06-03 07:15:38 +00:00
setOutParam ( getFunction ( api . functions , "GuiDropdownBox" ) , 2 ) ;
setOutParam ( getFunction ( api . functions , "GuiSpinner" ) , 2 ) ;
setOutParam ( getFunction ( api . functions , "GuiValueBox" ) , 2 ) ;
setOutParam ( getFunction ( api . functions , "GuiListView" ) , 2 ) ;
2023-06-05 19:38:33 +00:00
// const setStringListParam = (fun: RayLibFunction, index: number, indexLen: number) => {
// const lenParam = fun!.params![indexLen]
// lenParam.binding = { ignore: true }
// const param = fun!.params![index]
// fun.binding = { customizeCall: "int returnVal = GuiListViewEx(bounds, text, count, focus, scrollIndex, active);" }
// param.binding = {
// jsType: `{ ${param.name}: string[] }`,
// customConverter: (gen,src) => {
// gen.line("// TODO: Read string values")
// },
// customCleanup: (gen, src) => {
// gen.line("// TODO: Dispose strings")
// }
// }
// }
//const glve = getFunction(api.functions, "GuiListViewEx")!
//setStringListParam(glve, 1,2)
//setOutParam(glve, 3)
//setOutParam(glve, 4)
2023-06-02 16:58:53 +00:00
ignore ( "GuiListViewEx" ) ;
2023-06-04 11:41:18 +00:00
setOutParamString ( getFunction ( api . functions , "GuiTextBox" ) , 1 , 2 ) ;
2023-06-04 20:31:15 +00:00
const gtib = getFunction ( api . functions , "GuiTextInputBox" ) ;
setOutParamString ( gtib , 4 , 5 ) ;
setOutParam ( gtib , 6 ) ;
2023-06-05 19:38:33 +00:00
// needs string array
2023-06-02 16:58:53 +00:00
ignore ( "GuiTabBar" ) ;
2023-06-03 07:15:38 +00:00
ignore ( "GuiGetIcons" ) ;
2023-06-02 16:58:53 +00:00
ignore ( "GuiLoadIcons" ) ;
api . structs . forEach ( x => core . addApiStruct ( x ) ) ;
api . functions . forEach ( x => core . addApiFunction ( x ) ) ;
2023-05-14 20:19:47 +00:00
api . defines . filter ( x => x . type === "COLOR" ) . map ( x => ( { name : x . name , description : x . description , values : ( x . value . match ( /\{([^}]+)\}/ ) || "" ) [ 1 ] . split ( ',' ) . map ( x => x . trim ( ) ) } ) ) . forEach ( x => {
core . exportGlobalStruct ( "Color" , x . name , x . values , x . description ) ;
2023-05-08 21:37:58 +00:00
} ) ;
2023-06-02 16:58:53 +00:00
api . enums . forEach ( x => core . addEnum ( x ) ) ;
2023-06-13 21:03:38 +00:00
core . exportGlobalInt ( "MATERIAL_MAP_DIFFUSE" , "Albedo material (same as: MATERIAL_MAP_DIFFUSE" ) ;
core . exportGlobalInt ( "MATERIAL_MAP_SPECULAR" , "Metalness material (same as: MATERIAL_MAP_SPECULAR)" ) ;
2023-05-14 20:19:47 +00:00
core . writeTo ( "src/bindings/js_raylib_core.h" ) ;
core . typings . writeTo ( "examples/lib.raylib.d.ts" ) ;
2023-06-02 16:58:53 +00:00
const ignored = api . functions . filter ( x => x . binding ? . ignore ) . length ;
console . log ( ` Converted ${ api . functions . length - ignored } function. ${ ignored } ignored ` ) ;
console . log ( "Success!" ) ;
2023-06-11 10:49:26 +00:00
// TODO: Expose PLatform defines
2023-05-06 21:43:40 +00:00
}
main ( ) ;
} ) ( ) ;
/******/ } ) ( )
;