2023-05-14 20:19:47 +00:00
|
|
|
import { ApiFunction, ApiStruct } from "./api";
|
|
|
|
import { GenericCodeGenerator, FunctionArgument, CodeWriter } from "./generation"
|
|
|
|
import { writeFileSync } from "fs";
|
|
|
|
import { StructBindingOptions } from "./raylib-header";
|
|
|
|
|
|
|
|
export class TypeScriptDeclaration {
|
|
|
|
root = new TypescriptGenerator()
|
|
|
|
structs: TypescriptGenerator;
|
|
|
|
functions: TypescriptGenerator;
|
|
|
|
constants: TypescriptGenerator;
|
|
|
|
|
|
|
|
constructor(){
|
|
|
|
this.structs = this.root.child()
|
|
|
|
this.functions = this.root.child()
|
|
|
|
this.constants = this.root.child()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addFunction(name: string, api: ApiFunction){
|
|
|
|
const para = api.params.map(x => ({ name: x.name, type: this.toJsType(x.type)}))
|
|
|
|
const returnType = this.toJsType(api.returnType)
|
|
|
|
this.functions.tsDeclareFunction(name, para, returnType, api.description)
|
|
|
|
}
|
|
|
|
|
|
|
|
addStruct(api: ApiStruct, options: StructBindingOptions){
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
private toJsType(type: string){
|
|
|
|
switch(type){
|
|
|
|
case "int":
|
|
|
|
case "long":
|
|
|
|
case "unsigned int":
|
|
|
|
case "unsigned char":
|
|
|
|
case "float":
|
|
|
|
case "double":
|
|
|
|
return "number"
|
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 *":
|
|
|
|
return "string"
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public writeTo(filename: string){
|
|
|
|
const writer = new CodeWriter()
|
|
|
|
writer.writeGenerator(this.root)
|
|
|
|
writeFileSync(filename, writer.toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export abstract class GenericTypescriptGenerator<T extends TypescriptGenerator> extends GenericCodeGenerator<T> {
|
|
|
|
|
|
|
|
tsDeclareFunction(name: string, parameters: FunctionArgument[], returnType: string, description: string){
|
|
|
|
this.tsDocComment(description)
|
|
|
|
this.statement(`declare function ${name}(${parameters.map(x => x.name + ': '+x.type).join(', ')}): ${returnType}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
tsDeclareConstant(name: string, type: string, description: string){
|
|
|
|
this.tsDocComment(description)
|
|
|
|
this.statement(`declare var ${name}: ${type}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
tsDeclareType(name: string, hasConstructor: boolean, parameters: FunctionArgument[]){
|
|
|
|
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: string, fields: FunctionArgument[]){
|
|
|
|
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: string){
|
|
|
|
this.line(`/** ${comment} */`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TypescriptGenerator extends GenericTypescriptGenerator<TypescriptGenerator> {
|
|
|
|
createGenerator(): TypescriptGenerator {
|
|
|
|
return new TypescriptGenerator()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|