322 lines
7.6 KiB
JavaScript
322 lines
7.6 KiB
JavaScript
class CppParameter
|
|
{
|
|
name = "";
|
|
type = "";
|
|
}
|
|
|
|
class CppClassMember
|
|
{
|
|
name = "";
|
|
isMethod = false;
|
|
isVirtual = false;
|
|
isStatic = false;
|
|
isSignal = false;
|
|
type = "void";
|
|
initialValue = null;
|
|
parameters = [];
|
|
|
|
constructor( nameDefinition, body )
|
|
{
|
|
if ( nameDefinition.indexOf( "()" ) != -1)
|
|
{
|
|
this.isMethod = true;
|
|
|
|
let typeRegex = /\(\)\s*(?:\:\s*(.+)\s*)?$/;
|
|
let result = typeRegex.exec( nameDefinition );
|
|
|
|
if ( result[ 1 ] )
|
|
{
|
|
this.type = result[ 1 ];
|
|
}
|
|
|
|
nameDefinition = nameDefinition.replace( typeRegex, "" );
|
|
}
|
|
|
|
let names = nameDefinition.split( /\s+/ );
|
|
this.name = names[ names.length -1 ];
|
|
|
|
for ( let i = 0; i < names.length - 1; i++ )
|
|
{
|
|
if ( "virtual" === names[ i ] )
|
|
{
|
|
this.isVirtual = true;
|
|
}
|
|
|
|
if ( "static" === names[ i ] )
|
|
{
|
|
this.isStatic = true;
|
|
}
|
|
|
|
if ( "signal" === names[ i ] )
|
|
{
|
|
this.isSignal = true;
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.isMethod )
|
|
{
|
|
this.parseMethodBody( body );
|
|
}
|
|
else
|
|
{
|
|
this.parseVariableBody( body );
|
|
}
|
|
}
|
|
|
|
get isMemberWithInitialValue()
|
|
{
|
|
return ! this.isMethod && this.initialValue !== null;
|
|
}
|
|
|
|
getMemberInitializer()
|
|
{
|
|
return `${this.name} = ${this.initialValue};`;
|
|
}
|
|
|
|
|
|
parseVariableBody( body )
|
|
{
|
|
if ( typeof body === "boolean" )
|
|
{
|
|
this.type = "bool";
|
|
this.initialValue = body + "";
|
|
return;
|
|
}
|
|
|
|
if ( typeof body === "number" )
|
|
{
|
|
this.type = "float";
|
|
this.initialValue = body + "";
|
|
return;
|
|
}
|
|
|
|
let regex = /((?:\w|\<|\>)+)(?:\s*\=\s*(.+))?/;
|
|
let result = regex.exec( body );
|
|
|
|
this.type = result[ 1 ];
|
|
|
|
this.initialValue = result[ 2 ] || null;
|
|
|
|
}
|
|
|
|
parseMethodBody( body )
|
|
{
|
|
if ( ! body )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( typeof body === "string" )
|
|
{
|
|
this.type = body;
|
|
|
|
return;
|
|
}
|
|
|
|
for ( let it in body )
|
|
{
|
|
if ( ! body.hasOwnProperty( it ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
let cppParameter = new CppParameter();
|
|
cppParameter.name = it;
|
|
cppParameter.type = body[ it ];
|
|
|
|
this.parameters.push( cppParameter );
|
|
}
|
|
|
|
}
|
|
|
|
getMethodBinding( className )
|
|
{
|
|
if ( ! this.isMethod )
|
|
{
|
|
let type = stringToVariantType( this.type );
|
|
|
|
let bindings = [];
|
|
|
|
bindings.push( `/* ${this.name}: ${this.type} */` );
|
|
bindings.push( `ClassDB::bind_method(D_METHOD("get_${this.name}"), &${className}::get_${this.name});` );
|
|
bindings.push( `ClassDB::bind_method(D_METHOD("set_${this.name}"), &${className}::set_${this.name});` );
|
|
bindings.push( `ADD_PROPERTY(PropertyInfo(Variant::${type}, "${this.name}"), "set_${this.name}", "get_${this.name}");` );
|
|
bindings.push( ` ` );
|
|
|
|
//ClassDB::bind_method(D_METHOD("set_color", "color"), &GLTFLight::set_color);
|
|
//ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); // Color
|
|
|
|
return bindings.join( "\n " );
|
|
|
|
}
|
|
|
|
if ( this.isSignal )
|
|
{
|
|
//ADD_SIGNAL(MethodInfo("session_supported", PropertyInfo(Variant::STRING, "session_mode"), PropertyInfo(Variant::BOOL, "supported")));
|
|
let parameterInfos = "";
|
|
|
|
for ( let i = 0; i < this.parameters.length; i++ )
|
|
{
|
|
let type = stringToVariantType( this.parameters[ i ].type );
|
|
let name = this.parameters[ i ].name;
|
|
|
|
let pi = `, PropertyInfo(Variant::${type}, "${name}")`;
|
|
|
|
parameterInfos += pi;
|
|
}
|
|
|
|
return `ADD_SIGNAL (MethodInfo( "${this.name}" ${parameterInfos}) );`;
|
|
}
|
|
else if ( this.isVirtual )
|
|
{
|
|
let parameterInfos = "";
|
|
|
|
for ( let i = 0; i < this.parameters.length; i++ )
|
|
{
|
|
let name = `, "${this.parameters[ i ].name}"`;
|
|
|
|
parameterInfos += name;
|
|
}
|
|
|
|
return `GDVIRTUAL_BIND( ${this.name}${parameterInfos} );`;
|
|
}
|
|
else
|
|
{
|
|
return `ClassDB::bind_method( D_METHOD( "${this.name}" ) , &${className}::${this.name} );`
|
|
}
|
|
}
|
|
|
|
getHeaderDefinition()
|
|
{
|
|
if ( this.isSignal )
|
|
{
|
|
return `/* signal ${this.name} */`;
|
|
}
|
|
else if ( this.isMethod )
|
|
{
|
|
return this.getMethodHeaderDefinition();
|
|
}
|
|
else
|
|
{
|
|
return this.getVariableHeaderDefinition();
|
|
}
|
|
}
|
|
|
|
getParametersDefinition()
|
|
{
|
|
return this.parameters.map( p => p.type + " " + p.name ).join( ", " );
|
|
}
|
|
|
|
getMethodHeaderDefinition()
|
|
{
|
|
if ( this.isVirtual )
|
|
{
|
|
let numParameters = this.parameters.length;
|
|
let methodReturnType = this.type === "void" ? "" : "R";
|
|
let returnTypeDefinition = this.type === "void" ? "" : ( this.type + ", " ) ;
|
|
|
|
let parametersDefinition = "";
|
|
|
|
if ( numParameters > 0 )
|
|
{
|
|
parametersDefinition = ", " + this.parameters.map( p => p.type ).join( ", " );
|
|
}
|
|
|
|
|
|
return `GDVIRTUAL${numParameters}${methodReturnType}( ${returnTypeDefinition}${this.name}${parametersDefinition} );`
|
|
}
|
|
|
|
return `${this.type} ${this.name}(${this.parametersDefinition});`
|
|
}
|
|
|
|
getVariableHeaderDefinition()
|
|
{
|
|
return `${this.type} get_${this.name}(); void set_${this.name}( ${this.type} p_${this.name} );`
|
|
//return `${this.type} ${this.name};`
|
|
}
|
|
|
|
getPropertyHeaderDefinition()
|
|
{
|
|
return `${this.type} ${this.name};`
|
|
}
|
|
|
|
getPropertyImplementation( className )
|
|
{
|
|
let bindings = [];
|
|
|
|
bindings.push( `/* ${this.name}: ${this.type} */` );
|
|
bindings.push( `${this.type} ${className}::get_${this.name}() { return ${this.name}; }` );
|
|
bindings.push( `void ${className}::set_${this.name}( ${this.type} p_${this.name} ) { ${this.name} = p_${this.name}; }` );
|
|
bindings.push( ` ` );
|
|
|
|
return bindings.join( "\n" );
|
|
}
|
|
|
|
}
|
|
|
|
module.exports =
|
|
{
|
|
CppParameter,
|
|
CppClassMember
|
|
}
|
|
|
|
|
|
function stringToVariantType( stringType )
|
|
{
|
|
if ( /^TypedArray\<.+\>$/.test( stringType ) )
|
|
{
|
|
return "ARRAY";
|
|
}
|
|
|
|
switch( stringType )
|
|
{
|
|
case "bool": return "BOOL";
|
|
case "int": return "INT";
|
|
case "float": return "FLOAT";
|
|
case "String": return "STRING";
|
|
|
|
// Math types.
|
|
case "Vector2": return "VECTOR2";
|
|
case "Vector2i": return "VECTOR2I";
|
|
case "Rect2": return "RECT2";
|
|
case "Rect2i": return "RECT2I";
|
|
case "Transform2D": return "TRANSFORM2D";
|
|
case "Vector3": return "VECTOR3";
|
|
case "Vector3i": return "VECTOR3I";
|
|
case "Vector4": return "VECTOR4";
|
|
case "Vector4i": return "VECTOR4I";
|
|
case "Plane": return "PLANE";
|
|
case "AABB": return "AABB";
|
|
case "Quaternion": return "QUATERNION";
|
|
case "Basis": return "BASIS";
|
|
case "Transform3D": return "TRANSFORM3D";
|
|
case "Projection": return "PROJECTION";
|
|
|
|
// Miscellaneous types.
|
|
case "Color": return "COLOR";
|
|
case "RID": return "RID";
|
|
case "Object": return "OBJECT";
|
|
case "Callable": return "CALLABLE";
|
|
case "Signal": return "SIGNAL";
|
|
case "StringName": return "STRING_NAME";
|
|
case "NodePath": return "NODE_PATH";
|
|
case "Dictionary": return "DICTIONARY";
|
|
case "Array": return "ARRAY";
|
|
|
|
// Arrays.
|
|
case "PackedByteArray": return "PACKED_BYTE_ARRAY";
|
|
case "PackedInt32Array": return "PACKED_INT32_ARRAY";
|
|
case "PackedInt64Array": return "PACKED_INT64_ARRAY";
|
|
case "PackedFloat32Array": return "PACKED_FLOAT32_ARRAY";
|
|
case "PackedFloat64Array": return "PACKED_FLOAT64_ARRAY";
|
|
case "PackedStringArray": return "PACKED_STRING_ARRAY";
|
|
case "PackedVector2Array": return "PACKED_VECTOR2_ARRAY";
|
|
case "PackedVector3Array": return "PACKED_VECTOR3_ARRAY";
|
|
case "PackedColorArray": return "PACKED_COLOR_ARRAY";
|
|
}
|
|
|
|
console.error( "Type could not be mapped: ", stringType );
|
|
|
|
return "OBJECT";
|
|
} |