34. Listening for Attribute Changes

This commit is contained in:
2024-04-22 00:30:29 -04:00
parent 7db411586e
commit a6dc269630
24 changed files with 305 additions and 44 deletions

View File

@ -17,6 +17,197 @@ using namespace gen;
#include "GasaGen_UGasaAttributeSet.cpp"
#include "GasaGen_ChangeBPActionMenu.cpp"
#include "GasaGen_DevOptionsCache.cpp"
#include "GasaGen_HostWidgetController.cpp"
void gen_UHostWidgetController()
{
Array<StringCached> attribute_fields = get_gasa_attribute_fields();
CodeBody ori_HostWidgetController_header = parse_file(path_gasa_ui "HostWidgetController.h");
{
CodeBody header_body = def_body(ECode::Global_Body);
StrC str_UHostWidgetController = txt("UHostWidgetController");
CodeClass ori_UHostWidgetController = NoCode;
Code file_code = ori_HostWidgetController_header.begin();
for ( ; file_code != ori_HostWidgetController_header.end(); ++ file_code )
{
if (s32 never_enter = 0; never_enter)
found: break;
switch (file_code->Type)
{
default:
header_body.append(file_code);
continue;
case ECode::Class:
if ( ! file_code->Name.starts_with(str_UHostWidgetController))
continue;
ori_UHostWidgetController = file_code.cast<CodeClass>();
++ file_code;
goto found;
case ECode::Preprocess_Include:
header_body.append(file_code);
if ( file_code->Content.starts_with(txt("HostWidgetController.generated.h")))
{
header_body.append(fmt_newline);
header_body.append(fmt_newline);
}
continue;
case ECode::Untyped:
header_body.append(file_code);
if (file_code->Content.starts_with( txt("DECLARE_"))
|| file_code->Content.starts_with( txt("UCLASS"))
)
header_body.append(fmt_newline);
continue;
}
}
CodeBody attribute_events = def_body(ECode::Class_Body);
{
attribute_events.append( def_comment( txt("Attribute Events are generated by GasaGen/GasaGen_HostWidgetController.cpp")));
attribute_events.append(fmt_newline);
for ( s32 id = 0; id < attribute_fields.num(); )
{
StringCached attribute_field = attribute_fields[id];
attribute_events.append( code_str(
UPROPERTY(BlueprintAssignable, Category = "Attributes")
));
attribute_events.append(fmt_newline);
attribute_events.append( parse_variable(
token_fmt( "field", (StrC) attribute_field, stringize( FAttributeFloatChangedSig Event_On<field>Changed; ))
));
++ id;
if ( id < attribute_fields.num() )
{
attribute_events.append(fmt_newline);
}
}
}
CodeClass new_UHostWidgetController = ori_UHostWidgetController.duplicate().cast<CodeClass>();
CodeBody new_body = def_body(ECode::Class_Body);
for (Code code = ori_UHostWidgetController->Body.begin();
code != ori_UHostWidgetController->Body.end();
++ code )
{
switch (code->Type)
{
default:
new_body.append(code);
continue;
case ECode::Preprocess_Pragma:
{
local_persist bool found = false;
if (found)
{
new_body.append(code);
continue;
}
CodePragma pragma = code.cast<CodePragma>();
if ( pragma->Content.starts_with(txt("region Attribute Events")) )
{
new_body.append(pragma);
++ code;
new_body.append(attribute_events);
while (code->Type != ECode::Preprocess_Pragma
|| ! code->Content.starts_with(txt("endregion Attribute Events")))
++ code;
new_body.append( code );
found = true;
}
}
break;
case ECode::Untyped:
new_body.append(code);
if (code->Content.starts_with( txt("GENERATED_BODY")))
new_body.append(fmt_newline);
}
}
new_body.append(fmt_newline);
new_UHostWidgetController->Body = new_body;
header_body.append(new_UHostWidgetController);
for (; file_code != ori_HostWidgetController_header.end(); ++ file_code)
{
header_body.append(file_code);
}
Builder header = Builder::open(path_gasa_ui "HostWidgetController.h");
header.print(header_body);
header.write();
format_file(path_gasa_ui "HostWidgetController.h");
}
CodeBody ori_HostWidgetController_source = parse_file(path_gasa_ui "HostWidgetController.cpp");
{
CodeBody source_body = def_body(ECode::Global_Body);
CodeBody broadcast_calls = def_body(ECode::Function_Body);
for (StringCached field : attribute_fields)
{
broadcast_calls.append( code_fmt( "field", (StrC)field,
stringize( Event_On<field>Changed.Broadcast( GasaAttribs->Get<field>() ); )
));
}
CodeFn BroadcastInitialValues = parse_function( token_fmt( "broadcast_calls", (StrC)broadcast_calls.to_string(),
stringize(
void UHostWidgetController::BroadcastInitialValues()
{
Super::BroadcastInitialValues();
// Thiis function is managed by: GasaGen/GasaGen_HostWidgetController.cpp
UGasaAttributeSet* GasaAttribs = Cast<UGasaAttributeSet>(Data.Attributes);
if (GasaAttribs)
{
<broadcast_calls>
}
})
));
for ( Code code : ori_HostWidgetController_source)
{
switch (code->Type)
{
case ECode::Function:
CodeFn function_def = code.cast<CodeFn>();
if ( String::are_equal(function_def->Name, BroadcastInitialValues->Name)
&& function_def->Params.is_equal(BroadcastInitialValues->Params))
{
code = BroadcastInitialValues;
log_fmt("Swapped: %S", BroadcastInitialValues->Name);
}
break;
}
source_body.append(code);
}
Builder source = Builder::open(path_gasa_ui "HostWidgetController.cpp");
source.print(source_body);
source.write();
format_file(path_gasa_ui "HostWidgetController.cpp");
}
}
int gen_main()
{
@ -38,6 +229,7 @@ int gen_main()
PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_OneParam));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_ThreeParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_SixParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams));
@ -77,6 +269,7 @@ int gen_main()
gen_UGasaAttributeSet();
gen_FGasaDevOptionsCache();
gen_UHostWidgetController();
// One offs
if (0)

View File

@ -13,11 +13,13 @@ using namespace gen;
#define path_config path_source "Config/"
#define path_module_gasa path_source "Gasa/"
#define path_gasa_ability_system path_module_gasa "AbilitySystem/"
#define path_gasa_ui path_module_gasa "UI/"
constexpr StrC str_DECLARE_CLASS = txt("DECLARE_CLASS(");
constexpr StrC str_DECLARE_DELEGATE_RetVal_OneParam = txt("DECLARE_DELEGATE_RetVal_OneParam(");
constexpr StrC str_DECLARE_DELEGATE_RetVal_ThreeParams = txt("DECLARE_DELEGATE_RetVal_ThreeParams(");
constexpr StrC str_DECLARE_DELEGATE_SixParams = txt("DECLARE_DELEGATE_SixParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams(");

View File

@ -16,16 +16,26 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name
void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties );
void impl_attribute_fields ( CodeBody body, StrC class_name, Array<StringCached> properties );
Array<StringCached> get_gasa_attribute_fields()
{
local_persist
Array<StringCached> attribute_fields = Array<StringCached>::init_reserve(GlobalAllocator, 64);
for (local_persist s32 do_once = 0; do_once == 0; ++ do_once) {
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")));
}
return attribute_fields;
}
void gen_UGasaAttributeSet()
{
CodeType type_UAttributeSet = def_type( txt("UAttributeSet") );
CodeComment generation_notice = def_comment(txt("Generated by GasaGen/GasaGen_UGasaAttributeSet.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")));
Array<StringCached> attribute_fields = get_gasa_attribute_fields();
StrC class_name = txt("UGasaAttributeSet");

View File

@ -1950,6 +1950,7 @@ void CodeFn::to_string_def( String& result )
if ( ast->Attributes )
result.append_fmt( " %S ", ast->Attributes.to_string() );
b32 prefix_specs = false;
if ( ast->Specs )
{
for ( SpecifierT spec : ast->Specs )
@ -1958,11 +1959,13 @@ void CodeFn::to_string_def( String& result )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
prefix_specs = true;
}
}
}
if ( ast->Attributes || ast->Specs )
if ( ast->Attributes || prefix_specs )
result.append( "\n" );
if ( ast->ReturnType )
@ -2000,19 +2003,22 @@ void CodeFn::to_string_fwd( String& result )
if ( ast->Attributes )
result.append_fmt( "%S ", ast->Attributes.to_string() );
bool prefix_specs = false;
if ( ast->Specs )
{
for ( SpecifierT spec : ast->Specs )
{
if ( ESpecifier::is_trailing( spec ) && ! ( spec != ESpecifier::Pure ) )
if ( ! ESpecifier::is_trailing( spec ) || ! ( spec != ESpecifier::Pure ) )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
prefix_specs = true;
}
}
}
if ( ast->Attributes || ast->Specs )
if ( ast->Attributes || prefix_specs )
{
result.append( "\n" );
}
@ -2894,17 +2900,17 @@ internal void define_constants()
access_private = make_code();
access_private->Type = ECode::Access_Private;
access_private->Name = get_cached_string( txt( "private:" ) );
access_private->Name = get_cached_string( txt( "private:\n" ) );
access_private.set_global();
access_protected = make_code();
access_protected->Type = ECode::Access_Protected;
access_protected->Name = get_cached_string( txt( "protected:" ) );
access_protected->Name = get_cached_string( txt( "protected:\n" ) );
access_protected.set_global();
access_public = make_code();
access_public->Type = ECode::Access_Public;
access_public->Name = get_cached_string( txt( "public:" ) );
access_public->Name = get_cached_string( txt( "public:\n" ) );
access_public.set_global();
attrib_api_export = def_attributes( code( GEN_API_Export_Code ) );

View File

@ -5146,6 +5146,9 @@ Code CodeParam::duplicate()
bool CodeParam::is_equal( Code other )
{
if ( ast == nullptr && other.ast == nullptr)
return true;
if ( ast == nullptr || other.ast == nullptr )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );