rokojori-godot/rokojori-cpp-generator/source/cpp-creation/members/Field.ts

197 lines
5.9 KiB
TypeScript

import { RJLog } from "../../library/RJLog";
import { GodotTypes } from "../GodotTypes";
import { MemberInitializer } from "../MemberInitializer";
import { MemberType } from "../MemberType";
import { Member } from "./Member";
export class Field extends Member
{
static readonly Node = "Node";
static readonly Resource = "Resource";
constructor( memberInitializer:MemberInitializer )
{
super( MemberType.Field, memberInitializer );
}
isReference = false;
referenceType = "";
isProperty = false;
propertySignalName = "";
propertyActionName = "";
parseBody( body:any )
{
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 );
let typeOrRefRegex = /^(Ref|Resource|Node)</;
let refRegex = /^Ref<(\w+)>/;
let typeResult = result[ 1 ]
this.isReference = typeOrRefRegex.test( typeResult );
// RJLog.log( "Is Reference", this.name, this.isReference, typeResult );
if ( this.isReference )
{
this.referenceType = refRegex.test( typeResult ) ? refRegex.exec( typeResult )[ 1 ] :
typeOrRefRegex.exec( typeResult )[ 1 ];
// RJLog.log( "referenceType", body, `"${this.referenceType}"`, typeResult );
if ( Field.Node === this.referenceType )
{
typeResult = typeResult.replace( typeOrRefRegex, "" ).replace( />$/, "");
typeResult = typeResult + "*";
}
else
{
typeResult = typeResult.replace( typeOrRefRegex, "Ref<" );
if ( result.length >= 2 )
{
this.initialValue = result[ 2 ];
}
}
}
this.type = typeResult;
this.initialValue = result[ 2 ] || null;
}
getFieldDeclaration()
{
let fieldInfo = "\n " + this.info() + "\n ";
if ( Field.Node === this.referenceType )
{
return `${fieldInfo}${this.type} ${this.name} = nullptr;`;
}
return `${fieldInfo}${this.type} ${this.name};`
}
getHeaderDefinition():string
{
let fieldInfo = "\n " + this.info() + "\n ";
if ( Field.Node === this.referenceType )
{
return `${fieldInfo}${this.type} get_${this.name}() const; void set_${this.name}( ${this.type} p_${this.name} );`;
}
if ( Field.Resource === this.referenceType )
{
return `${fieldInfo}${this.type} get_${this.name}() const; void set_${this.name}( const ${this.type} &p_${this.name} );`;
}
return `${fieldInfo}${this.type} get_${this.name}(); void set_${this.name}( ${this.type} p_${this.name} );`
}
getBindings( className:string ):string
{
let bindings = [];
bindings.push( `// ${this.name}: ${this.type}` );
bindings.push( `ClassDB::bind_method( D_METHOD( "set_${this.name}", "${this.name}" ), &${className}::set_${this.name} );` );
bindings.push( `ClassDB::bind_method( D_METHOD( "get_${this.name}"), &${className}::get_${this.name});` );
if ( this.isReference )
{
// ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "reference_property", PROPERTY_HINT_NODE_TYPE), "set_reference_property", "get_reference_property");
// RJLog.log( "Searching propertyHint:", this.name, this.type, this.referenceType );
let propertyHint = GodotTypes.stringToPropertyHint( this.referenceType );
bindings.push( `ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "${this.name}", ${propertyHint} ), "set_${this.name}", "get_${this.name}" );` );
}
else
{
let type = GodotTypes.stringToVariantType( this.type );
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 " );
}
getFieldImplementation( className:string )
{
let implementations = [];
implementations.push( `// ${this.name}: ${this.type}` );
let eventCallbacks = "";
if ( this.isProperty )
{
eventCallbacks += `\n`;
eventCallbacks += `\n emit_signal( SNAME( "${this.propertySignalName}" ) );`;
eventCallbacks += `\n`;
eventCallbacks += `\n if ( ${this.propertyActionName} != NULL )`;
eventCallbacks += `\n {`;
eventCallbacks += `\n ${this.propertyActionName}->trigger();`;
eventCallbacks += `\n }`;
}
let n = this.isProperty ? "\n" : "";
let n2 = this.isProperty ? "\n " : "";
if ( Field.Node === this.referenceType )
{
implementations.push( `${this.type} ${className}::get_${this.name}() const { return ${this.name}; }` );
implementations.push( `void ${className}::set_${this.name}( ${this.type} p_${this.name} ) ${n}{${n2} ${this.name} = p_${this.name};${eventCallbacks} ${n}}` );
}
else if ( Field.Resource === this.referenceType )
{
implementations.push( `${this.type} ${className}::get_${this.name}() const { return ${this.name}; }` );
implementations.push( `void ${className}::set_${this.name}( const ${this.type} &p_${this.name} ) ${n}{${n2} ${this.name} = p_${this.name};${eventCallbacks} ${n}}` );
}
else
{
implementations.push( `${this.type} ${className}::get_${this.name}() { return ${this.name}; }` );
implementations.push( `void ${className}::set_${this.name}( ${this.type} p_${this.name} ) ${n}{${n2} ${this.name} = p_${this.name};${eventCallbacks} ${n}}` );
}
implementations.push( ` ` );
return implementations.join( "\n" );
}
get hasInitializer()
{
return this.initialValue !== null;
}
getInitializer()
{
return `${this.name} = ${this.initialValue};`;
}
}