diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.dll b/Project/Binaries/Win64/UnrealEditor-Gasa.dll index f72d045..a0a19cb 100644 --- a/Project/Binaries/Win64/UnrealEditor-Gasa.dll +++ b/Project/Binaries/Win64/UnrealEditor-Gasa.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:839a8eeeb78730a282fab857d06caf01eefc94b90c8814a9aaa2c4b8354e7f2b -size 585216 +oid sha256:4dc552693e832f77c50d1798b39b0f7b0b7c5e771951edffa7eb91e4723693eb +size 591360 diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb index 5a83b60..9b34ea4 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb and b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb differ diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll index 0092aa3..5e36bb4 100644 --- a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll +++ b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9141dea5d29e14a1cf866fe6323fc1e6ca94cb24fef1d1c8b69aad83bd820d4 +oid sha256:037b5602ab6b914d4756edf9acda7211d4e166267268137bd2be8b9cb146d253 size 79360 diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb index 9f59f37..094a141 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb and b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb differ diff --git a/Project/Config/DefaultGame.ini b/Project/Config/DefaultGame.ini index 41d3140..830df19 100644 --- a/Project/Config/DefaultGame.ini +++ b/Project/Config/DefaultGame.ini @@ -9,7 +9,7 @@ Tag_PPV=Global_PPV Tag_GlobalPPV=Global_PPV Template_PlayerCamera=/Game/Actors/BP_CameraMount.BP_CameraMount_C Template_HUD_HostUI=/Game/UI/UI_Host.UI_Host_C -Template_HostWidgetController=/Game/Core/BP_HostWidgetController.BP_HostWidgetController_C +Template_HostWidgetController=/Game/UI/BP_HostWidgetController.BP_HostWidgetController_C [/Script/GameplayAbilities.AbilitySystemGlobals] bUseDebugTargetFromHud=true diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp index 03c3d33..b061639 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp @@ -8,9 +8,9 @@ UGasaAttributeSet::UGasaAttributeSet() { - InitHealth( 100.f ); + InitHealth( 80.f ); InitMaxHealth( 100.f ); - InitMana( 50.f ); + InitMana( 20.f ); InitMaxMana( 50.f ); } @@ -33,7 +33,6 @@ void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMan { GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxMana, PrevMaxMana ) } - void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray& OutLifetimeProps ) const { Super::GetLifetimeReplicatedProps( OutLifetimeProps ); diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h index b279735..898ea2c 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h @@ -90,7 +90,6 @@ public: #pragma endregion Setters #pragma region UObject - void GetLifetimeReplicatedProps( TArray& OutLifetimeProps ) const override; #pragma endregion UObject diff --git a/Project/Source/Gasa/Characters/PlayerCharacter.cpp b/Project/Source/Gasa/Characters/PlayerCharacter.cpp index 34a830e..cfe19cc 100644 --- a/Project/Source/Gasa/Characters/PlayerCharacter.cpp +++ b/Project/Source/Gasa/Characters/PlayerCharacter.cpp @@ -28,7 +28,7 @@ void APlayerCharacter::PossessedBy(AController* NewController) AGasaPlayerController* PC = GetController(); AGasaHUD* HUD = PC->GetHUD(); FWidgetControllerData Data = { PC, PS, AbilitySystem, Attributes }; - HUD->InitOverlay(& Data); + HUD->InitHostWidget(& Data); } // TODO(Ed): We need to setup Net Slime... @@ -49,6 +49,6 @@ void APlayerCharacter::OnRep_PlayerState() AGasaPlayerController* PC = GetController(); AGasaHUD* HUD = PC->GetHUD(); FWidgetControllerData Data = { PC, PS, AbilitySystem, Attributes }; - HUD->InitOverlay(& Data); + HUD->InitHostWidget(& Data); } } diff --git a/Project/Source/Gasa/UI/GasaHUD.cpp b/Project/Source/Gasa/UI/GasaHUD.cpp index eb2093e..0de61f1 100644 --- a/Project/Source/Gasa/UI/GasaHUD.cpp +++ b/Project/Source/Gasa/UI/GasaHUD.cpp @@ -6,14 +6,16 @@ #include "Blueprint/UserWidget.h" using namespace Gasa; -void AGasaHUD::InitOverlay(FWidgetControllerData const* WidgetControllerData) +void AGasaHUD::InitHostWidget(FWidgetControllerData const* WidgetControllerData) { HostWidget = CreateWidget( GetWorld() , GetDevOptions()->Template_HUD_HostUI.LoadSynchronous() ); HostWidgetController = NewObject(this, GetDevOptions()->Template_HostWidgetController.Get()); + HostWidgetController->Data = (* WidgetControllerData); HostWidget->SetWidgetController(HostWidgetController); - + + HostWidgetController->BroadcastInitialValues(); HostWidget->AddToViewport(); } diff --git a/Project/Source/Gasa/UI/GasaHUD.h b/Project/Source/Gasa/UI/GasaHUD.h index bc4543c..2d63150 100644 --- a/Project/Source/Gasa/UI/GasaHUD.h +++ b/Project/Source/Gasa/UI/GasaHUD.h @@ -19,7 +19,7 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadWrite) TObjectPtr HostWidgetController; - void InitOverlay(FWidgetControllerData const* WidgetControllerData); + void InitHostWidget(FWidgetControllerData const* WidgetControllerData); #pragma region HUD void ShowHUD() override; diff --git a/Project/Source/Gasa/UI/GlobeProgressBar.cpp b/Project/Source/Gasa/UI/GlobeProgressBar.cpp index 4276bd3..949455c 100644 --- a/Project/Source/Gasa/UI/GlobeProgressBar.cpp +++ b/Project/Source/Gasa/UI/GlobeProgressBar.cpp @@ -89,6 +89,11 @@ void UGlobeProgressBar::SetGlassStyle(FSlateBrush brush) Glass->SetBrush(brush); } +void UGlobeProgressBar::SetPercentage(float CurrentValue, float MaxValue) +{ + Bar->SetPercent( MaxValue > 0.f ? CurrentValue / MaxValue : 0.f ); +} + void UGlobeProgressBar::SetSize(float width, float height) { Root_SB->SetWidthOverride( width ); diff --git a/Project/Source/Gasa/UI/GlobeProgressBar.h b/Project/Source/Gasa/UI/GlobeProgressBar.h index 766e4a6..3a92387 100644 --- a/Project/Source/Gasa/UI/GlobeProgressBar.h +++ b/Project/Source/Gasa/UI/GlobeProgressBar.h @@ -46,6 +46,9 @@ public: UFUNCTION(BlueprintCallable, Category="Globe") void SetGlassStyle(FSlateBrush brush); + + UFUNCTION(BlueprintCallable, Category="Globe") + void SetPercentage(float CurrentValue, float MaxValue); UFUNCTION(BlueprintCallable, Category="Globe") void SetSize(float width, float height); diff --git a/Project/Source/Gasa/UI/HostWIdgetController.cpp b/Project/Source/Gasa/UI/HostWIdgetController.cpp index 27f22a5..b4e1294 100644 --- a/Project/Source/Gasa/UI/HostWIdgetController.cpp +++ b/Project/Source/Gasa/UI/HostWIdgetController.cpp @@ -1 +1,14 @@ -#include "HostWidgetController.h" +#include "HostWidgetController.h" +#include "AbilitySystem/GasaAttributeSet.h" +void UHostWidgetController::BroadcastInitialValues() +{ + Super::BroadcastInitialValues(); + UGasaAttributeSet* GasaAttribs = Cast( Data.Attributes ); + if ( GasaAttribs ) + { + Event_OnHealthChanged.Broadcast( GasaAttribs->GetHealth() ); + Event_OnMaxHealthChanged.Broadcast( GasaAttribs->GetMaxHealth() ); + Event_OnManaChanged.Broadcast( GasaAttribs->GetMana() ); + Event_OnMaxManaChanged.Broadcast( GasaAttribs->GetMaxMana() ); + } +} diff --git a/Project/Source/Gasa/UI/HostWidgetController.h b/Project/Source/Gasa/UI/HostWidgetController.h index 571711a..ebe8072 100644 --- a/Project/Source/Gasa/UI/HostWidgetController.h +++ b/Project/Source/Gasa/UI/HostWidgetController.h @@ -1,12 +1,31 @@ -#pragma once +#pragma once #include "WidgetController.h" - #include "HostWidgetController.generated.h" +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FAttributeFloatChangedSig, float, NewValue ); -UCLASS() +UCLASS( Blueprintable, BlueprintType ) class GASA_API UHostWidgetController : public UWidgetController { GENERATED_BODY() public: +#pragma region Attribute Events + // Attribute Events are generated by GasaGen/GasaGen_HostWidgetController.cpp + + UPROPERTY( BlueprintAssignable, Category = "Attributes" ) + FAttributeFloatChangedSig Event_OnHealthChanged; + + UPROPERTY( BlueprintAssignable, Category = "Attributes" ) + FAttributeFloatChangedSig Event_OnMaxHealthChanged; + + UPROPERTY( BlueprintAssignable, Category = "Attributes" ) + FAttributeFloatChangedSig Event_OnManaChanged; + + UPROPERTY( BlueprintAssignable, Category = "Attributes" ) + FAttributeFloatChangedSig Event_OnMaxManaChanged; +#pragma endregion Attribute Events + +#pragma region WidgetController + void BroadcastInitialValues() override; +#pragma endregion WidgetController }; diff --git a/Project/Source/Gasa/UI/WidgetController.h b/Project/Source/Gasa/UI/WidgetController.h index 8c678d4..cdd05e0 100644 --- a/Project/Source/Gasa/UI/WidgetController.h +++ b/Project/Source/Gasa/UI/WidgetController.h @@ -7,27 +7,19 @@ USTRUCT(BlueprintType) struct GASA_API FWidgetControllerData { GENERATED_BODY() - +public: FWidgetControllerData() = default; - FWidgetControllerData(AGasaPlayerController* Controller - , AGasaPlayerState* PlayerState - , UAbilitySystemComponent* AbilitySystem - , UAttributeSet* Attributes ) -#if 1 + FWidgetControllerData + ( AGasaPlayerController* Controller + , AGasaPlayerState* PlayerState + , UAbilitySystemComponent* AbilitySystem + , UAttributeSet* Attributes ) : Controller(Controller) , PlayerState(PlayerState) , AbilitySystem(AbilitySystem) , Attributes(Attributes) -#endif - { -#if 0 - this->Controller = Controller; - this->PlayerState = PlayerState; - this->AbilitySystem = AbilitySystem; - this->Attributes = Attributes; -#endif - } + {} UPROPERTY(BlueprintReadOnly, Category="Player") TObjectPtr Controller; @@ -50,4 +42,7 @@ public: UPROPERTY(BlueprintReadOnly, Category="Player") FWidgetControllerData Data; + + UFUNCTION() + virtual void BroadcastInitialValues() {}; }; diff --git a/Project/Source/GasaGen/GasaGen.cpp b/Project/Source/GasaGen/GasaGen.cpp index 72ed2db..eee4d98 100644 --- a/Project/Source/GasaGen/GasaGen.cpp +++ b/Project/Source/GasaGen/GasaGen.cpp @@ -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 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(); + ++ 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_OnChanged; )) + )); + + ++ id; + if ( id < attribute_fields.num() ) + { + attribute_events.append(fmt_newline); + } + } + } + + CodeClass new_UHostWidgetController = ori_UHostWidgetController.duplicate().cast(); + 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(); + 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_OnChanged.Broadcast( GasaAttribs->Get() ); ) + )); + } + + 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(Data.Attributes); + if (GasaAttribs) + { + + } + }) + )); + + for ( Code code : ori_HostWidgetController_source) + { + switch (code->Type) + { + case ECode::Function: + CodeFn function_def = code.cast(); + + 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) diff --git a/Project/Source/GasaGen/GasaGenCommon.cpp b/Project/Source/GasaGen/GasaGenCommon.cpp index cd87619..5711000 100644 --- a/Project/Source/GasaGen/GasaGenCommon.cpp +++ b/Project/Source/GasaGen/GasaGenCommon.cpp @@ -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("); diff --git a/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp b/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp index a6f2e70..e585258 100644 --- a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp +++ b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp @@ -16,16 +16,26 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name void def_attribute_field_initers ( CodeBody body, Array properties ); void impl_attribute_fields ( CodeBody body, StrC class_name, Array properties ); +Array get_gasa_attribute_fields() +{ + local_persist + Array attribute_fields = Array::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 attribute_fields = Array::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 attribute_fields = get_gasa_attribute_fields(); StrC class_name = txt("UGasaAttributeSet"); diff --git a/Project/Source/GasaGen/gen.cpp b/Project/Source/GasaGen/gen.cpp index c1e185f..c6299d2 100644 --- a/Project/Source/GasaGen/gen.cpp +++ b/Project/Source/GasaGen/gen.cpp @@ -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 ) ); diff --git a/Project/Source/GasaGen/gen.hpp b/Project/Source/GasaGen/gen.hpp index 34ef386..26fa9b1 100644 --- a/Project/Source/GasaGen/gen.hpp +++ b/Project/Source/GasaGen/gen.hpp @@ -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!" ); diff --git a/scripts/.clang-format b/scripts/.clang-format index e2f5968..4f14293 100644 --- a/scripts/.clang-format +++ b/scripts/.clang-format @@ -166,7 +166,16 @@ SpacesInSquareBrackets: false Standard: c++20 -StatementMacros: ['UPROPERTY', 'UFUNCTION', 'UCLASS', 'USTRUCT', 'UENUM', 'UINTERFACE', 'GENERATED_BODY'] +StatementMacros: [ + 'UPROPERTY', + 'UFUNCTION', + 'UCLASS', + 'USTRUCT', + 'UENUM', + 'UINTERFACE', + 'GENERATED_BODY', + 'DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam' +] TabWidth: 4 diff --git a/scripts/gen_pass_gasa.ps1 b/scripts/gen_pass_gasa.ps1 index ee4953d..63b7cba 100644 --- a/scripts/gen_pass_gasa.ps1 +++ b/scripts/gen_pass_gasa.ps1 @@ -79,6 +79,7 @@ function build-gengasa $compiler_args = @() $compiler_args += ($flag_define + 'GEN_TIME') + $compiler_args += ($flag_cpp_version + 'c++17') $linker_args = @() $linker_args += $flag_link_win_subsystem_console diff --git a/scripts/helpers/vendor_toolchain.ps1 b/scripts/helpers/vendor_toolchain.ps1 index 8dcf5f1..329881c 100644 --- a/scripts/helpers/vendor_toolchain.ps1 +++ b/scripts/helpers/vendor_toolchain.ps1 @@ -94,6 +94,7 @@ if ( $vendor -match "clang" ) # https://clang.llvm.org/docs/ClangCommandLineReference.html $flag_all_c = '-x c' $flag_all_cpp = '-x c++' + $flag_cpp_version = '-std=' $flag_compile = '-c' $flag_color_diagnostics = '-fcolor-diagnostics' $flag_no_color_diagnostics = '-fno-color-diagnostics' @@ -318,6 +319,7 @@ if ( $vendor -match "msvc" ) # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 $flag_all_c = '/TC' $flag_all_cpp = '/TP' + $flag_cpp_version = '/std:' $flag_compile = '/c' $flag_debug = '/Zi' $flag_define = '/D'