GASATHON/Project/Source/GasaGen/GasaGen.cpp
Ed_ ced71b6a22 24. Health and Mana
Decided to try using gencpp for the first time with UE (just codegen, not parsing).

I used it to generate the AttributeSet
2024-04-13 16:18:57 -04:00

179 lines
5.4 KiB
C++

#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND
// #define GEN_DEFINE_ATTRIBUTE_TOKENS
#define GEN_IMPLEMENTATION
#include "gen.cpp"
#include "gen.builder.cpp"
using namespace gen;
// Program assumes its working directory is the project
#define path_config "./Source/Config/"
#define path_module_gasa "./Source/Gasa/"
#define path_gasa_ability_system path_module_gasa "AbilitySystem/"
void def_attribute_fields( CodeBody body, Array<StringCached> fields )
{
for ( String field : fields )
{
Code field_uproperty = code_str(
UPROPERTY(ReplicatedUsing=Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category="Attributes")
);
CodeType type_FGameplayAttributeData = def_type( txt("FGameplayAttributeData"));
body.append(fmt_newline);
body.append( field_uproperty );
body.append(fmt_newline);
body.append( def_variable( type_FGameplayAttributeData, StrC(field)) );
}
}
void def_attribute_field_on_reps( CodeBody body, Array<StringCached> fields )
{
for ( String field : fields )
{
Code umeta_UFUNCTION = code_str( UFUNCTION() );
body.append(fmt_newline);
body.append( umeta_UFUNCTION );
body.append(fmt_newline);
body.append( code_fmt( "field", (StrC)field, stringize(
void Client_OnRep_<field>(FGameplayAttributeData& Prev<field>);
)));
}
}
void impl_attribute_fields( CodeBody body, Array<StringCached> fields )
{
for ( String field : fields )
{
body.append(fmt_newline);
CodeFn field_impl = parse_function( token_fmt( "field", (StrC)field, stringize(
void UGasaAttributeSet::Client_OnRep_<field>(FGameplayAttributeData& Prev<field>)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UGasaAttributeSet, <field>, Prev<field>)
}
)));
body.append( field_impl );
}
}
int gen_main()
{
gen::init();
log_fmt("Generating code for the Gasa module");
Code umeta_uclass = code_str( UCLASS() );
Code umeta_generated_body = code_str( GENERATED_BODY() );
Code gasa_api = code_str( GASA_API );
CodeType type_UAttributeSet = def_type( txt("UAttributeSet") );
CodeComment generation_notice = def_comment(txt("This was generated by GasaGen/GasaGen.cpp"));
Array<StringCached> attribute_fields = Array<StringCached>::init( GlobalAllocator);
attribute_fields.append( get_cached_string(txt("Health")));
attribute_fields.append( get_cached_string(txt("MaxHealth")));
attribute_fields.append( get_cached_string(txt("Mana")));
attribute_fields.append( get_cached_string(txt("MaxMana")));
Builder header = Builder::open( path_gasa_ability_system "GasaAttributeSet.h");
{
header.print(generation_notice);
header.print(fmt_newline);
{
CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h"));
CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h"));
CodeAttributes attributes = def_attributes( gasa_api->Name);
CodeClass GasaAttributeSet = {};
{
CodeBody body = def_body( CodeT::Class_Body );
{
body.append( umeta_generated_body);
body.append( fmt_newline);
body.append( access_public );
def_attribute_fields( body, attribute_fields);
body.append(fmt_newline);
body.append( def_constructor() );
def_attribute_field_on_reps( body, attribute_fields);
body.append(fmt_newline);
body.append(fmt_newline);
body.append( def_pragma( txt("region UObject")));
body.append( parse_function( code(
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
)));
body.append( def_pragma( txt("endregion UObject")));
}
GasaAttributeSet = def_class( txt("UGasaAttributeSet"), body
, type_UAttributeSet
, AccessSpec::Public
, attributes
);
}
header.print( Include_AttributeSet);
header.print( fmt_newline);
header.print( Include_GasaAttributeSet_Generated);
header.print( fmt_newline);
header.print(umeta_uclass);
header.print(GasaAttributeSet);
}
header.write();
}
Builder source = Builder::open( path_gasa_ability_system "GasaAttributeSet.cpp" );
{
source.print(generation_notice);
source.print( def_include( txt("GasaAttributeSet.h")));
source.print(fmt_newline);
source.print( def_include( txt("AbilitySystemComponent.h")));
source.print( def_include( txt("Net/UnrealNetwork.h")));
source.print( def_include( txt("Networking/GasaNetLibrary.h")));
{
CodeBody body = def_body( CodeT::Global_Body );
body.append(fmt_newline);
body.append(code_str(
UGasaAttributeSet::UGasaAttributeSet() {}
));
body.append(fmt_newline);
impl_attribute_fields(body, attribute_fields);
CodeFn GetLifetimeOfReplicatedProps;
{
CodeBody field_lifetimes = def_body( CodeT::Function_Body);
for (StringCached field : attribute_fields)
{
field_lifetimes.append( code_fmt( "field", (StrC)field, stringize(
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, <field>);
)));
}
GetLifetimeOfReplicatedProps = parse_function( token_fmt( "body", (StrC)(field_lifetimes.to_string()), stringize(
void UGasaAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
<body>
}
)));
}
body.append(GetLifetimeOfReplicatedProps);
source.print(body);
}
source.write();
}
// gen::deinit();
return 0;
}