diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ef0e50a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,43 @@ +root = true + +[*] +charset = utf-8 +indent_style = tab +indent_size = 4 +tab_width = 4 +trim_trailing_whitespace = false +max_line_length = 150 + +# MSBuild +[*.{csproj,proj,projitems,shproj,fsproj,target,props}] +indent_style = space +indent_size = 2 + +# XML config files +[*.{config,nuspec,resx,natvis}] +indent_style = space +indent_size = 2 + +[*.{h, c, hpp, cpp}] +indent_style = tab +indent_size = 4 + +[*.{ps1, psm1}] +indent_style = tab +indent_size = 4 + +[*.md] +indent_style = space +indent_size = 4 + + +[*.{natvis, natstepfilter}] +indent_style = tab +indent_size = 4 + +# Settings for Verse source files +[*.{verse,versetest}] +indent_style = space +indent_size = 4 +tab_width = 4 +max_line_length = off diff --git a/.gitignore b/.gitignore index 41e05ad..43a0fc0 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ Project/Binaries/GasaGen.map Project/Binaries/GasaGen.obj Project/Binaries/vc140.pdb Project/Saved/Config/ConsoleHistory.ini +*.pdb +Project/Saved/Diff diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..aa85bfc --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE", + "GASA_INTELLISENSE_DIRECTIVES=1" + ], + "windowsSdkVersion": "10.0.22621.0", + "compilerPath": "cl.exe" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 2ad6625..617274b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "name": "Debug GenGas vsdbg", "program": "${workspaceFolder}/Project/Binaries/GasaGen.exe", "args": [], - "cwd": "${workspaceFolder}/Project/", + "cwd": "${workspaceFolder}", "visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis" }, ] diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.dll b/Project/Binaries/Win64/UnrealEditor-Gasa.dll index e91f1b4..7fedcfd 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.dll and b/Project/Binaries/Win64/UnrealEditor-Gasa.dll differ diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb index 73f23fb..0958a4d 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 070861f..2e9273f 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll and b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll differ diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb index fa0bb04..cf3af54 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 0625065..ebc12cf 100644 --- a/Project/Config/DefaultGame.ini +++ b/Project/Config/DefaultGame.ini @@ -7,6 +7,9 @@ CopyrightNotice= [/Script/Gasa.GasaDevOptions] 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 [/Script/GameplayAbilities.AbilitySystemGlobals] bUseDebugTargetFromHud=true + diff --git a/Project/Content/Core/Game/BP_GameMode.uasset b/Project/Content/Core/Game/BP_GameMode.uasset index d45eb8a..b883a4a 100644 --- a/Project/Content/Core/Game/BP_GameMode.uasset +++ b/Project/Content/Core/Game/BP_GameMode.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f42e8e2282dc1199880cd6a9c86c322731c80b10231606d480526317c100d97 -size 15568 +oid sha256:572660b6583e07298a6d024d1d78316199dbd8422179a58172540561f216de34 +size 15934 diff --git a/Project/Content/Core/Game/BP_GasaPlayerState.uasset b/Project/Content/Core/Game/BP_GasaPlayerState.uasset index 86d215d..4879615 100644 --- a/Project/Content/Core/Game/BP_GasaPlayerState.uasset +++ b/Project/Content/Core/Game/BP_GasaPlayerState.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:477380e9532aed3041cb13cb65f17c35b21a1691846371d92ca006ba13201086 -size 20409 +oid sha256:c7cb08ff73ba59804f9f33cb80559316e7f25879e94f1a6362c0cb4f38fb5651 +size 15370 diff --git a/Project/Content/Core/Game/BP_HUD.uasset b/Project/Content/Core/Game/BP_HUD.uasset new file mode 100644 index 0000000..68446f3 --- /dev/null +++ b/Project/Content/Core/Game/BP_HUD.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cfa3675a02cb5c4ca8ef99f1a1fe7665e2426a55222b158fc0961850cac5f5e +size 14368 diff --git a/Project/Content/Core/Game/BP_PlayerController.uasset b/Project/Content/Core/Game/BP_PlayerController.uasset index 1a9e0c5..45784b6 100644 --- a/Project/Content/Core/Game/BP_PlayerController.uasset +++ b/Project/Content/Core/Game/BP_PlayerController.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5d879c96777c9fb46e97bf286cc8c93e36b6a3d134d8541166a94b5fa32a402 -size 14651 +oid sha256:a7e43fc43b030c3044b4b18d57ef14d76379ae177069d01c37f17113ef903cf0 +size 18209 diff --git a/Project/Content/UI/UI_GlobeHealth.uasset b/Project/Content/UI/UI_GlobeHealth.uasset new file mode 100644 index 0000000..aa390b8 --- /dev/null +++ b/Project/Content/UI/UI_GlobeHealth.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53d765b36d52e2e1333097bdbc53c29885c40042ded388489df3fec1be10cdc4 +size 37994 diff --git a/Project/Content/UI/UI_GlobeMana.uasset b/Project/Content/UI/UI_GlobeMana.uasset new file mode 100644 index 0000000..b9b95d7 --- /dev/null +++ b/Project/Content/UI/UI_GlobeMana.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a02428322028679874ad1e9ab706a135b20473976500427204881f086b0e59b +size 38440 diff --git a/Project/Content/UI/UI_GlobeProgressBar.uasset b/Project/Content/UI/UI_GlobeProgressBar.uasset deleted file mode 100644 index 8abccfd..0000000 --- a/Project/Content/UI/UI_GlobeProgressBar.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:474312ec301d4ea7ca56eacd11166125ec6e211164cc8dd757e6e95e7a804d31 -size 23143 diff --git a/Project/Content/UI/UI_GlobeTemplate.uasset b/Project/Content/UI/UI_GlobeTemplate.uasset new file mode 100644 index 0000000..40065f5 --- /dev/null +++ b/Project/Content/UI/UI_GlobeTemplate.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4aabe9c7bb90c3bf74ccd4b847fd61b5eedd23aed4a7cc9a6fbde849282c271 +size 24062 diff --git a/Project/Content/UI/UI_Host.uasset b/Project/Content/UI/UI_Host.uasset new file mode 100644 index 0000000..038ace1 --- /dev/null +++ b/Project/Content/UI/UI_Host.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a92e8df58c2f62bf23279be15b3bba3e5f56f43780629591e0f6f43a89f8d95 +size 14310 diff --git a/Project/Gasa.uproject b/Project/Gasa.uproject index d40bd5a..2439597 100644 --- a/Project/Gasa.uproject +++ b/Project/Gasa.uproject @@ -304,6 +304,46 @@ { "Name": "GitSourceControl", "Enabled": true + }, + { + "Name": "SlateInsights", + "Enabled": true + }, + { + "Name": "TraceUtilities", + "Enabled": true + }, + { + "Name": "NetworkPredictionInsights", + "Enabled": true + }, + { + "Name": "TraceSourceFilters", + "Enabled": true + }, + { + "Name": "GameplayInsights", + "Enabled": true + }, + { + "Name": "RenderGraphInsights", + "Enabled": true + }, + { + "Name": "BlueprintStats", + "Enabled": true + }, + { + "Name": "ColorCorrectRegions", + "Enabled": true + }, + { + "Name": "ControlFlows", + "Enabled": true + }, + { + "Name": "LiveUpdateForSlate", + "Enabled": true } ] } \ No newline at end of file diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp index bcc6fff..cf9577a 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp @@ -33,9 +33,10 @@ void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMan GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxMana, PrevMaxMana ) } -void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const +void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray& OutLifetimeProps ) const { Super::GetLifetimeReplicatedProps( OutLifetimeProps ); + DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Health ); DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxHealth ); DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Mana ); diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h index a612b0b..3faf0d7 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h @@ -4,7 +4,8 @@ #include "AbilitySystemComponent.h" #include "GasaAttributeSet.generated.h" -UCLASS() class GASA_API UGasaAttributeSet : public UAttributeSet +UCLASS() +class GASA_API UGasaAttributeSet : public UAttributeSet { GENERATED_BODY() public: @@ -21,6 +22,7 @@ public: FGameplayAttributeData MaxMana; UGasaAttributeSet(); + UFUNCTION() void Client_OnRep_Health( FGameplayAttributeData& PrevHealth ); UFUNCTION() @@ -31,55 +33,35 @@ public: void Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana ); #pragma region Getters - static FGameplayAttribute GetHealthAttribute() { - static FProperty* Prop = FindFieldChecked< FProperty >( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) ); + static FProperty* Prop = FindFieldChecked( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) ); return Prop; } - static FGameplayAttribute GetMaxHealthAttribute() { - static FProperty* Prop = FindFieldChecked< FProperty >( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) ); + static FProperty* Prop = FindFieldChecked( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) ); return Prop; } - static FGameplayAttribute GetManaAttribute() { - static FProperty* Prop = FindFieldChecked< FProperty >( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) ); + static FProperty* Prop = FindFieldChecked( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) ); return Prop; } - static FGameplayAttribute GetMaxManaAttribute() { - static FProperty* Prop = FindFieldChecked< FProperty >( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); + static FProperty* Prop = FindFieldChecked( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); return Prop; } - - FORCEINLINE float GetHealth() const - { - return Health.GetCurrentValue(); - } - - FORCEINLINE float GetMaxHealth() const - { - return MaxHealth.GetCurrentValue(); - } - - FORCEINLINE float GetMana() const - { - return Mana.GetCurrentValue(); - } - - FORCEINLINE float GetMaxMana() const - { - return MaxMana.GetCurrentValue(); - } - -#pragma endregion Getters + FORCEINLINE float GetHealth() const { return Health.GetCurrentValue(); } + FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); } + FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); } + FORCEINLINE float GetMaxMana() const { return MaxMana.GetCurrentValue(); } + #pragma endregion Getters #pragma region Setters - FORCEINLINE void SetHealth( float NewVal ) + FORCEINLINE void + SetHealth( float NewVal ) { UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); if ( ensure( AbilityComp ) ) @@ -87,7 +69,6 @@ public: AbilityComp->SetNumericAttributeBase( GetHealthAttribute(), NewVal ); }; } - FORCEINLINE void SetMaxHealth( float NewVal ) { UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); @@ -96,7 +77,6 @@ public: AbilityComp->SetNumericAttributeBase( GetMaxHealthAttribute(), NewVal ); }; } - FORCEINLINE void SetMana( float NewVal ) { UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); @@ -105,7 +85,6 @@ public: AbilityComp->SetNumericAttributeBase( GetManaAttribute(), NewVal ); }; } - FORCEINLINE void SetMaxMana( float NewVal ) { UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); @@ -114,44 +93,39 @@ public: AbilityComp->SetNumericAttributeBase( GetMaxManaAttribute(), NewVal ); }; } - FORCEINLINE void InitHealth( float NewVal ) { Health.SetBaseValue( NewVal ); Health.SetCurrentValue( NewVal ); } - FORCEINLINE void InitMaxHealth( float NewVal ) { MaxHealth.SetBaseValue( NewVal ); MaxHealth.SetCurrentValue( NewVal ); } - FORCEINLINE void InitMana( float NewVal ) { Mana.SetBaseValue( NewVal ); Mana.SetCurrentValue( NewVal ); } - FORCEINLINE void InitMaxMana( float NewVal ) { MaxMana.SetBaseValue( NewVal ); MaxMana.SetCurrentValue( NewVal ); } - -#pragma endregion Setters + #pragma endregion Setters #pragma region UObject - void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override; + void + GetLifetimeReplicatedProps( TArray& OutLifetimeProps ) const override; #pragma endregion UObject }; - namespace Gasa { inline UGasaAttributeSet const* GetAttributeSet( UAbilitySystemComponent* ASC ) { - return Cast< UGasaAttributeSet >( ASC->GetAttributeSet( UGasaAttributeSet::StaticClass() ) ); + return Cast( ASC->GetAttributeSet( UGasaAttributeSet::StaticClass() ) ); } } diff --git a/Project/Source/Gasa/Game/GasaPlayerController.cpp b/Project/Source/Gasa/Game/GasaPlayerController.cpp index 09c1090..8006539 100644 --- a/Project/Source/Gasa/Game/GasaPlayerController.cpp +++ b/Project/Source/Gasa/Game/GasaPlayerController.cpp @@ -4,6 +4,7 @@ #include "Engine/LocalPlayer.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" +#include "GasaDevOptions.h" #include "GasaPlayerState.h" #include "Actors/CameraMount.h" #include "Camera/CameraComponent.h" @@ -12,6 +13,8 @@ #include "GameFramework/SpringArmComponent.h" #include "Kismet/KismetSystemLibrary.h" +using namespace Gasa; + AGasaPlayerController::AGasaPlayerController() { PrimaryActorTick.bCanEverTick = true; @@ -21,11 +24,14 @@ AGasaPlayerController::AGasaPlayerController() bReplicates = true; } +#pragma region Input void AGasaPlayerController::Move(FInputActionValue const& ActionValue) { APawn* pawn = GetPawn(); if (pawn == nullptr ) return; + + // Note(Ed): I did the follow optimization for practice, they are completely unnecessary for this context. #if 0 @@ -63,6 +69,13 @@ void AGasaPlayerController::Move(FInputActionValue const& ActionValue) pawn->AddMovementInput( MoveDir ); #endif } +#pragma endregion Input + +#pragma region PlayerController +void AGasaPlayerController::SpawnDefaultHUD() +{ + Super::SpawnDefaultHUD(); +} void AGasaPlayerController::OnPossess(APawn* InPawn) { @@ -86,7 +99,6 @@ void AGasaPlayerController::OnUnPossess() Super::OnUnPossess(); } -#pragma region PlayerController void AGasaPlayerController::PlayerTick(float DeltaTime) { Super::PlayerTick(DeltaTime); @@ -162,7 +174,7 @@ void AGasaPlayerController::PostInitializeComponents() { Super::PostInitializeComponents(); - Cam = GetWorld()->SpawnActor(CamClass, FActorSpawnParameters() ); + Cam = GetWorld()->SpawnActor(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() ); SetViewTarget(Cam); } diff --git a/Project/Source/Gasa/Game/GasaPlayerController.h b/Project/Source/Gasa/Game/GasaPlayerController.h index 05cfd29..08c5025 100644 --- a/Project/Source/Gasa/Game/GasaPlayerController.h +++ b/Project/Source/Gasa/Game/GasaPlayerController.h @@ -12,9 +12,6 @@ class GASA_API AGasaPlayerController : public APlayerController GENERATED_BODY() public: #pragma region Camera - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf CamClass; - UPROPERTY(EditAnywhere, BlueprintReadWrite) TObjectPtr Cam; #pragma endregion Camera @@ -60,6 +57,8 @@ public: } #pragma region PlayerController + void SpawnDefaultHUD() override; + void OnPossess(APawn* InPawn) override; void OnUnPossess() override; diff --git a/Project/Source/Gasa/Game/GasaViewport.cpp b/Project/Source/Gasa/Game/GasaViewport.cpp new file mode 100644 index 0000000..2db5f2d --- /dev/null +++ b/Project/Source/Gasa/Game/GasaViewport.cpp @@ -0,0 +1 @@ +#include "GasaViewport.h" diff --git a/Project/Source/Gasa/Game/GasaViewport.h b/Project/Source/Gasa/Game/GasaViewport.h new file mode 100644 index 0000000..5f59d00 --- /dev/null +++ b/Project/Source/Gasa/Game/GasaViewport.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Engine/GameViewportClient.h" + +#include "GasaViewport.generated.h" + +UCLASS() +class GASA_API UGasaViewport : public UGameViewportClient +{ + GENERATED_BODY() +public: +}; diff --git a/Project/Source/Gasa/Gasa.Build.cs b/Project/Source/Gasa/Gasa.Build.cs index a9e9ee7..b2abffc 100644 --- a/Project/Source/Gasa/Gasa.Build.cs +++ b/Project/Source/Gasa/Gasa.Build.cs @@ -33,9 +33,17 @@ public class Gasa : ModuleRules "NetCore", "Niagara", "SlateCore", - "UMG", + "UMG", }); - #endregion Engine + + if (Target.bBuildEditor) + { + PrivateDependencyModuleNames.AddRange( new string[] { + "UnrealEd", + "UMGEditor", + }); + } + #endregion Engine #region Plugins if (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Type != TargetRules.TargetType.Server) @@ -66,5 +74,6 @@ public class Gasa : ModuleRules #endregion Plugins PublicIncludePaths.Add("Gasa"); + PublicIncludePathModuleNames.Add("Gasa"); } } diff --git a/Project/Source/Gasa/GasaCommon.h b/Project/Source/Gasa/GasaCommon.h index 36dc8e7..dd0ab7a 100644 --- a/Project/Source/Gasa/GasaCommon.h +++ b/Project/Source/Gasa/GasaCommon.h @@ -48,6 +48,7 @@ class UGasaImage; class UGasaOverlay; class UGasaProgressBar; class UGasaSizeBox; +class UUI_HostWidget; #pragma endregion Forwards #pragma region Logging @@ -98,7 +99,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogGasa, Log, All); namespace Gasa { using ELogV = EGasaVerbosity; - + //◞ ‸ ◟// // Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now) inline @@ -111,7 +112,7 @@ namespace Gasa { #if !UE_BUILD_SHIPPING && !NO_LOGGING ELogVerbosity::Type EngineVerbosity = (ELogVerbosity::Type) Verbosity; - + static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic; static UE::Logging::Private::FStaticBasicLogRecord LOG_Static(TEXT("%s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic); @@ -132,13 +133,13 @@ namespace Gasa } } -#define GASA_Fatal(Message) UE_LOG( Gasa, Fatal, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_FILE(), __func__, __builtin_LINE() ); -#define GASA_Error(Message) UE_LOG( Gasa, Error, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); -#define GASA_Warning(Message) UE_LOG( Gasa, Warning, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); -#define GASA_Display(Message) UE_LOG( Gasa, Display, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); -#define GASA_Log(Message) UE_LOG( Gasa, Log, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); -#define GASA_Verbose(Message) UE_LOG( Gasa, Verbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); -#define GASA_VeryVerbose(Message) UE_LOG( Gasa, VeryVerbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_Fatal(Message) UE_LOG( LogGasa, Fatal, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_FILE(), __func__, __builtin_LINE() ); +#define GASA_Error(Message) UE_LOG( LogGasa, Error, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_Warning(Message) UE_LOG( LogGasa, Warning, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_Display(Message) UE_LOG( LogGasa, Display, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_Log(Message) UE_LOG( LogGasa, Log, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_Verbose(Message) UE_LOG( LogGasa, Verbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GASA_VeryVerbose(Message) UE_LOG( LogGasa, VeryVerbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); #pragma endregion Logging #pragma region Timing @@ -154,8 +155,8 @@ namespace Gasa constexpr float _80Hz = .013f; constexpr float _90Hz = .011f; constexpr float _100Hz = .010f; - constexpr float _120Hz = .083f; + constexpr float _120Hz = .008f; constexpr float _240Hz = .004f; constexpr float _480Hz = .002f; } -#pragma endregion Timing \ No newline at end of file +#pragma endregion Timing diff --git a/Project/Source/Gasa/GasaDevOptions.cpp b/Project/Source/Gasa/GasaDevOptions.cpp index d5b0bad..ffd96d1 100644 --- a/Project/Source/Gasa/GasaDevOptions.cpp +++ b/Project/Source/Gasa/GasaDevOptions.cpp @@ -1,18 +1,11 @@ -#include "GasaDevOptions.h" +#include "GasaDevOptions.h" -#include "GasaDevOptionsCache.h" +#include "Actors/CameraMount.h" +#include "UI/UI_HostWidget.h" + +using namespace Gasa; namespace Gasa { global FName Tag_GlobalPPV; } - -void FGasaDevOptionsCache::CachedDevOptions() -{ - using namespace Gasa; - - UGasaDevOptions const* DevOs = GetDevOptions(); - Tag_GlobalPPV = DevOs->Tag_GlobalPPV; -} - - \ No newline at end of file diff --git a/Project/Source/Gasa/GasaDevOptions.h b/Project/Source/Gasa/GasaDevOptions.h index 3a43e00..0415792 100644 --- a/Project/Source/Gasa/GasaDevOptions.h +++ b/Project/Source/Gasa/GasaDevOptions.h @@ -1,7 +1,9 @@ -#pragma once +#pragma once #include "Engine/DeveloperSettings.h" +#include "GasaCommon.h" + #include "GasaDevOptions.generated.h" UCLASS(Config=Game, DefaultConfig, meta=(DisplayName="Gasa")) @@ -9,6 +11,16 @@ class GASA_API UGasaDevOptions : public UDeveloperSettings { GENERATED_BODY() public: + + // NOTE(Ed): Any Soft-References must have their includes defined in GasaDevOptions.cpp + // They are used by GasaGen for the GasaDevOptionsCache + + UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI") + TSoftClassPtr Template_PlayerCamera; + + UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI") + TSoftClassPtr Template_HUD_HostUI; + UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Tags") FName Tag_GlobalPPV; }; @@ -19,11 +31,11 @@ namespace Gasa FORCEINLINE UGasaDevOptions const* GetDevOptions() { - return GetDefault(); + return GetDefault(); } FORCEINLINE UGasaDevOptions* GetMutDevOptions() { - return GetMutableDefault(); + return GetMutableDefault(); } } diff --git a/Project/Source/Gasa/GasaDevOptionsCache.cpp b/Project/Source/Gasa/GasaDevOptionsCache.cpp new file mode 100644 index 0000000..3983ed2 --- /dev/null +++ b/Project/Source/Gasa/GasaDevOptionsCache.cpp @@ -0,0 +1,17 @@ +// This was generated by GasaGen/GasaGen.cpp +#include "GasaDevOptionsCache.h" + +#include "GasaDevOptions.h" +#include "Actors/CameraMount.h" +#include "UI/UI_HostWidget.h" +using namespace Gasa; + +void FGasaDevOptionsCache::CachedDevOptions() +{ + UGasaDevOptions* DevOpts = GetMutDevOptions(); + + Template_PlayerCamera = DevOpts->Template_PlayerCamera.LoadSynchronous(); + Template_HUD_HostUI = DevOpts->Template_HUD_HostUI.LoadSynchronous(); + + Tag_GlobalPPV = DevOpts->Tag_GlobalPPV; +} diff --git a/Project/Source/Gasa/GasaDevOptionsCache.h b/Project/Source/Gasa/GasaDevOptionsCache.h index 3726b37..fb6ed94 100644 --- a/Project/Source/Gasa/GasaDevOptionsCache.h +++ b/Project/Source/Gasa/GasaDevOptionsCache.h @@ -1,6 +1,5 @@ -#pragma once - -#include "GasaCommon.h" +// This was generated by GasaGen/GasaGen.cpp +#pragma once #include "GasaDevOptionsCache.generated.h" @@ -8,6 +7,11 @@ USTRUCT() struct GASA_API FGasaDevOptionsCache { GENERATED_BODY() - + + UPROPERTY() + UClass* Template_PlayerCamera; + UPROPERTY() + UClass* Template_HUD_HostUI; + void CachedDevOptions(); }; diff --git a/Project/Source/Gasa/GasaViewport.cpp b/Project/Source/Gasa/GasaViewportSubsystem.cpp similarity index 100% rename from Project/Source/Gasa/GasaViewport.cpp rename to Project/Source/Gasa/GasaViewportSubsystem.cpp diff --git a/Project/Source/Gasa/GasaViewport.h b/Project/Source/Gasa/GasaViewportSubsystem.h similarity index 81% rename from Project/Source/Gasa/GasaViewport.h rename to Project/Source/Gasa/GasaViewportSubsystem.h index 5ea731d..fd57f0b 100644 --- a/Project/Source/Gasa/GasaViewport.h +++ b/Project/Source/Gasa/GasaViewportSubsystem.h @@ -2,7 +2,7 @@ #include "Blueprint/GameViewportSubsystem.h" -#include "GasaViewport.generated.h" +#include "GasaViewportSubsystem.generated.h" UCLASS() class GASA_API UGasaViewportSubsystem : public UGameViewportSubsystem @@ -12,4 +12,4 @@ public: // UGasaViewportSubsystem(); -}; +}; \ No newline at end of file diff --git a/Project/Source/Gasa/ScratchMeta.h b/Project/Source/Gasa/ScratchMeta.h deleted file mode 100644 index 0f82c4c..0000000 --- a/Project/Source/Gasa/ScratchMeta.h +++ /dev/null @@ -1,9 +0,0 @@ -// Don't keep this included anywhere -// Purely for inspection purposes - -#include "GasaCommon.h" - -void test() -{ - UObject::StaticClass()->PropertiesSize -} diff --git a/Project/Source/Gasa/UI/GasaCanvas.cpp b/Project/Source/Gasa/UI/GasaCanvas.cpp new file mode 100644 index 0000000..e1283cf --- /dev/null +++ b/Project/Source/Gasa/UI/GasaCanvas.cpp @@ -0,0 +1 @@ +#include "GasaCanvas.h" diff --git a/Project/Source/Gasa/UI/GasaCanvas.h b/Project/Source/Gasa/UI/GasaCanvas.h new file mode 100644 index 0000000..2fa1f77 --- /dev/null +++ b/Project/Source/Gasa/UI/GasaCanvas.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Engine/Canvas.h" + +#include "GasaCanvas.generated.h" + +UCLASS() +class GASA_API UGasaCanvas : public UCanvas +{ + GENERATED_BODY() +public: +}; diff --git a/Project/Source/Gasa/UI/GasaCanvasPanel.cpp b/Project/Source/Gasa/UI/GasaCanvasPanel.cpp new file mode 100644 index 0000000..ea0098f --- /dev/null +++ b/Project/Source/Gasa/UI/GasaCanvasPanel.cpp @@ -0,0 +1 @@ +#include "GasaCanvasPanel.h" diff --git a/Project/Source/Gasa/UI/GasaCanvasPanel.h b/Project/Source/Gasa/UI/GasaCanvasPanel.h new file mode 100644 index 0000000..c43e931 --- /dev/null +++ b/Project/Source/Gasa/UI/GasaCanvasPanel.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Components/CanvasPanel.h" + +#include "GasaCanvasPanel.generated.h" + +UCLASS() +class GASA_API UGasaCanvasPanel : public UCanvasPanel +{ + GENERATED_BODY() +public: +}; diff --git a/Project/Source/Gasa/UI/GasaHUD.cpp b/Project/Source/Gasa/UI/GasaHUD.cpp new file mode 100644 index 0000000..eb78a1a --- /dev/null +++ b/Project/Source/Gasa/UI/GasaHUD.cpp @@ -0,0 +1,31 @@ +#include "GasaHUD.h" + +#include "GasaDevOptions.h" +#include "UI_HostWidget.h" +#include "Blueprint/UserWidget.h" + +using namespace Gasa; + + +#pragma region HUD +void AGasaHUD::ShowHUD() +{ + Super::ShowHUD(); +} +#pragma endregion HUD + +#pragma region Actor +UE_DISABLE_OPTIMIZATION +void AGasaHUD::BeginPlay() +{ + Super::BeginPlay(); + + HostWidget = CreateWidget( GetWorld() + , GetDevOptions()->Template_HUD_HostUI.LoadSynchronous() ); + HostWidget->AddToViewport(); + + bool bHostVis = HostWidget->IsVisible(); + Log(FString::Printf(TEXT("HostVIs: %s"), *FString::FromInt(bHostVis))); +} +UE_ENABLE_OPTIMIZATION +#pragma endregion Actor diff --git a/Project/Source/Gasa/UI/GasaHUD.h b/Project/Source/Gasa/UI/GasaHUD.h new file mode 100644 index 0000000..2de69eb --- /dev/null +++ b/Project/Source/Gasa/UI/GasaHUD.h @@ -0,0 +1,25 @@ +#pragma once + +#include "GasaCommon.h" +#include "GameFramework/HUD.h" + +#include "GasaHUD.generated.h" + + +UCLASS() +class GASA_API AGasaHUD : public AHUD +{ + GENERATED_BODY() +public: + UPROPERTY(VisibleAnywhere, BlueprintReadWrite) + TObjectPtr HostWidget; + +#pragma region HUD + void ShowHUD() override; +#pragma endregion HUD + +#pragma region Actor + void BeginPlay() override; + +#pragma endregion Actor +}; diff --git a/Project/Source/Gasa/UI/GasaProgressBar.cpp b/Project/Source/Gasa/UI/GasaProgressBar.cpp new file mode 100644 index 0000000..8f60e2a --- /dev/null +++ b/Project/Source/Gasa/UI/GasaProgressBar.cpp @@ -0,0 +1,22 @@ +#include "GasaProgressBar.h" + +#include "GasaCommon.h" + +using namespace Gasa; + +#pragma region Object +void UGasaProgressBar::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); +} + +void UGasaProgressBar::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); +} + +void UGasaProgressBar::Serialize(FStructuredArchive::FRecord Record) +{ + Super::Serialize(Record); +} +#pragma endregion Object diff --git a/Project/Source/Gasa/UI/GasaProgressBar.h b/Project/Source/Gasa/UI/GasaProgressBar.h index 81bdd87..1586f3f 100644 --- a/Project/Source/Gasa/UI/GasaProgressBar.h +++ b/Project/Source/Gasa/UI/GasaProgressBar.h @@ -10,4 +10,10 @@ class GASA_API UGasaProgressBar : public UProgressBar GENERATED_BODY() public: +#pragma region Object + void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; + + void Serialize(FArchive& Ar) override; + void Serialize(FStructuredArchive::FRecord Record) override; +#pragma endregion Object }; diff --git a/Project/Source/Gasa/UI/GasaUserWidget.cpp b/Project/Source/Gasa/UI/GasaUserWidget.cpp index 3327803..185916e 100644 --- a/Project/Source/Gasa/UI/GasaUserWidget.cpp +++ b/Project/Source/Gasa/UI/GasaUserWidget.cpp @@ -1,7 +1,310 @@ #include "GasaUserWidget.h" +#include "Blueprint/WidgetBlueprintGeneratedClass.h" +#include "Blueprint/WidgetTree.h" +#include "Components/HorizontalBoxSlot.h" +#include "Components/Overlay.h" +#include "Components/OverlaySlot.h" +#include "Components/ScaleBoxSlot.h" +#include "Components/ScrollBoxSlot.h" +#include "Components/SizeBoxSlot.h" +#include "Components/VerticalBoxSlot.h" + +#if WITH_EDITOR +#include "WidgetBlueprint.h" +#include "Kismet2/BlueprintEditorUtils.h" +#endif + +#if 0 +UWidget* UMyModalDialog::DeepDuplicateWidget(UWidget *pUWidget) +{ + UWidget *pNewWidget = DuplicateObject(pUWidget, this); + UPanelWidget *pNewUPanelWidget = Cast(pNewWidget); + if (pNewUPanelWidget) + { + const TArray& slots = pNewUPanelWidget->GetSlots(); + for (int32 iSlotNum = 0; iSlotNum < slots.Num(); ++iSlotNum) + { + slots[iSlotNum]->Content = nullptr; + } + pNewUPanelWidget->ClearChildren(); + UPanelWidget *pUPanelWidget = Cast(pUWidget); + for (int ii = 0; ii < pUPanelWidget->GetChildrenCount(); ++ii) + { + UWidget *pChildUWidget = pUPanelWidget->GetChildAt(ii); + UWidget *pNewChildWidget = DeepDuplicateWidget(pChildUWidget); + UPanelSlot *pUPanelSlot = pNewUPanelWidget->AddChild(pNewChildWidget); + UHorizontalBoxSlot *pNewUHorizontalBoxSlot = Cast(pUPanelSlot); + if (pNewUHorizontalBoxSlot) + { + UHorizontalBoxSlot *pUHorizontalBoxSlot = Cast(pChildUWidget->Slot); + pNewUHorizontalBoxSlot->SetHorizontalAlignment(pUHorizontalBoxSlot->HorizontalAlignment); + pNewUHorizontalBoxSlot->SetVerticalAlignment(pUHorizontalBoxSlot->VerticalAlignment); + } + USizeBoxSlot *pNewUSizeBoxSlot = Cast(pUPanelSlot); + if (pNewUSizeBoxSlot) + { + USizeBoxSlot *pUSizeBoxSlot = Cast(pChildUWidget->Slot); + pNewUSizeBoxSlot->SetHorizontalAlignment(pUSizeBoxSlot->HorizontalAlignment); + pNewUSizeBoxSlot->SetVerticalAlignment(pUSizeBoxSlot->VerticalAlignment); + } + } + } + + return pNewWidget; +} +#endif + +void UGasaUserWidget::OnLooseParentCompiled(UBlueprint* BP) +{ + GenerateParentHierarchyFromLooseParent(); +} + +// This was just an experiment to see how possible it would be to generate a WidgetTree from a parent reference without using the usual blueprint inheritance. +void UGasaUserWidget::GenerateParentHierarchyFromLooseParent() +{ +#if WITH_EDITOR + UWidgetBlueprintGeneratedClass* WBG_ParentClass = Cast(LooseParent); + UWidgetBlueprintGeneratedClass* WBG_Class = Cast(GetClass()); + if (WBG_ParentClass == nullptr) + return; + if (WBG_Class == nullptr) + return; + + UPackage* Package = WBG_Class->GetPackage(); + UWidgetBlueprint* BP = Cast(Package->FindAssetInPackage()); + UWidgetTree* WT = BP->WidgetTree; + + UPackage* UserParentPackage = WBG_ParentClass->GetPackage(); + UWidgetBlueprint* UserParentBP = Cast(UserParentPackage->FindAssetInPackage()); + UWidgetTree* UserParentWT = UserParentBP->WidgetTree; + + TArray UserParentWidgets; + UserParentWT->GetAllWidgets(UserParentWidgets); + for (UWidget* UserParentWidget : UserParentWidgets) + { + UWidget* OldWidget = nullptr; + UWidget* Widget = WT->FindWidget(UserParentWidget->GetFName()); + TArray Children; + UPanelWidget* Parent = nullptr; + + if (Widget == nullptr) + { + if (UserParentWidget->GetClass()->IsChildOf(UUserWidget::StaticClass())) + Widget = CreateWidget(WT, UserParentWidget->GetClass(), UserParentWidget->GetFName()); + else + Widget = NewObject(WT, UserParentWidget->GetClass(), UserParentWidget->GetFName(), RF_Transactional, UserParentWidget); + + if (WT->RootWidget == nullptr) + { + WT->RootWidget = Widget; + } + else + { + Parent = WT->FindWidget(UserParentWidget->GetParent()->GetFName()); + } + } + else + { + // The widget existed previously (most likely already ran this before or manually created) + // Try to preserve widget heiarchy attached to this if possible + Parent = Widget->GetParent(); + + UPanelWidget* Panel = Cast(Widget); + if (Panel) + { + Children = Panel->GetAllChildren(); + } + + OldWidget = Widget; + Widget = DuplicateObject(UserParentWidget, WT, UserParentWidget->GetFName()); + } + + UPanelWidget* NewPanel = Cast(Widget); + if (NewPanel) + { + const TArray& Slots = NewPanel->GetSlots(); + for (int32 Id = 0; Id < Slots.Num(); ++Id) + { + Slots[Id]->Content = nullptr; + } + NewPanel->ClearChildren(); + } + + if (Parent) + { + UPanelSlot* PSlot = Parent->AddChild(Widget); + UScaleBoxSlot* SlotScale = Cast(PSlot); + UScrollBoxSlot* SlotScroll = Cast(PSlot); + UOverlaySlot* SlotOverlay = Cast(PSlot); + UHorizontalBoxSlot* SlotHB = Cast(PSlot); + USizeBoxSlot* SlotSB = Cast(PSlot); + UVerticalBoxSlot* SlobVB = Cast(PSlot); + + if (SlotOverlay) + { + UOverlay* UPW_ParentOverlay = Cast(UserParentWidget->GetParent()); + UOverlaySlot* ParentSlot = Cast(UPW_ParentOverlay->GetSlots()[Parent->GetSlots().Num() - 1]); + SlotOverlay->SetPadding( ParentSlot->GetPadding()); + SlotOverlay->SetHorizontalAlignment( ParentSlot->GetHorizontalAlignment()); + SlotOverlay->SetVerticalAlignment( ParentSlot->GetVerticalAlignment()); + } + } + + //This may not need to happen since the children check to see if they need to be added back. + for (UWidget* Child : Children) + { + if (UserParentWT->FindWidget(Child->GetFName())) + continue; + UPanelSlot* PSlot = Cast(Widget)->AddChild(Child); + UScaleBoxSlot* SlotScale = Cast(PSlot); + UScrollBoxSlot* SlotScroll = Cast(PSlot); + UOverlaySlot* SlotOverlay = Cast(PSlot); + UHorizontalBoxSlot* SlotHB = Cast(PSlot); + USizeBoxSlot* SlotSB = Cast(PSlot); + UVerticalBoxSlot* SlobVB = Cast(PSlot); + + // I'm not entirely sure if this is possible this way... + if (SlotOverlay) + { + UOverlay* ParentOverlay = Cast(OldWidget->GetParent()); + UOverlaySlot* ParentSlot = Cast(ParentOverlay->GetSlots()[Parent->GetSlots().Num() - 1]); + SlotOverlay->SetPadding( ParentSlot->GetPadding()); + SlotOverlay->SetHorizontalAlignment( ParentSlot->GetHorizontalAlignment()); + SlotOverlay->SetVerticalAlignment( ParentSlot->GetVerticalAlignment()); + } + } + + if (OldWidget) + OldWidget->RemoveFromParent(); + } + + BP->Modify(); + FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(BP); +#endif +} + UGasaUserWidget::UGasaUserWidget(FObjectInitializer const& ObjectInitializer) : UUserWidget(ObjectInitializer) -{ - +{ +} + +bool UGasaUserWidget::Initialize() +{ + // If it's not initialized initialize it, as long as it's not the CDO, we never initialize the CDO. + if (!bInitialized && !HasAnyFlags(RF_ClassDefaultObject)) + { + // If this is a sub-widget of another UserWidget, default designer flags and player context to match those of the owning widget + if (UUserWidget* OwningUserWidget = GetTypedOuter()) + { +#if WITH_EDITOR + SetDesignerFlags(OwningUserWidget->GetDesignerFlags()); +#endif + SetPlayerContext(OwningUserWidget->GetPlayerContext()); + } + + UWidgetBlueprintGeneratedClass* BGClass = Cast(GetClass()); + // Only do this if this widget is of a blueprint class + if (BGClass) + { + BGClass->InitializeWidget(this); + } + else + { + InitializeNativeClassData(); + } + + if ( WidgetTree == nullptr ) + { + WidgetTree = NewObject(this, TEXT("WidgetTree"), RF_Transient); + } + else + { + WidgetTree->SetFlags(RF_Transient); + + InitializeNamedSlots(); + } + + // For backward compatibility, run the initialize event on widget that doesn't have a player context only when the class authorized it. + bool bClassWantsToRunInitialized = BGClass && BGClass->bCanCallInitializedWithoutPlayerContext; + if (!IsDesignTime() && (PlayerContext.IsValid() || bClassWantsToRunInitialized)) + { + NativeOnInitialized(); + } + +#if WITH_EDITOR + if (LooseParent && bUpdateOnParentCompile) + { + UWidgetBlueprintGeneratedClass* WBG_ParentClass = Cast(LooseParent); + UPackage* UserParentPackage = WBG_ParentClass->GetPackage(); + UWidgetBlueprint* UserParentBP = Cast(UserParentPackage->FindAssetInPackage()); + UWidgetTree* UserParentWT = UserParentBP->WidgetTree; + + if ( ! UserParentBP->OnCompiled().IsBoundToObject(this)) + { + UserParentBP->OnCompiled().AddUObject(this, & ThisClass::OnLooseParentCompiled); + } + } +#endif + + bInitialized = true; + return true; + } + + return false; +} + +void UGasaUserWidget::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + FName PropertyName = (PropertyChangedEvent.Property != NULL) ? PropertyChangedEvent.Property->GetFName() : NAME_None; + if (PropertyName == GET_MEMBER_NAME_CHECKED(UGasaUserWidget, LooseParent) + || PropertyName == GET_MEMBER_NAME_CHECKED(UGasaUserWidget, bUpdateOnParentCompile) ) + { +#if WITH_EDITOR + if (LooseParent && bUpdateOnParentCompile) + { + UWidgetBlueprintGeneratedClass* WBG_ParentClass = Cast(LooseParent); + if (WBG_ParentClass == nullptr) + return; + UPackage* UserParentPackage = WBG_ParentClass->GetPackage(); + UWidgetBlueprint* UserParentBP = Cast(UserParentPackage->FindAssetInPackage()); + UWidgetTree* UserParentWT = UserParentBP->WidgetTree; + + if ( ! UserParentBP->OnCompiled().IsBoundToObject(this)) + { + UserParentBP->OnCompiled().AddUObject(this, & ThisClass::OnLooseParentCompiled); + } + } +#endif + } +} + +void UGasaUserWidget::NativeOnInitialized() +{ + Super::NativeOnInitialized(); + +} + +void UGasaUserWidget::NativePreConstruct() +{ + Super::NativePreConstruct(); + +#if 0 + if (LooseParent) + { + UWidgetBlueprintGeneratedClass* WBG_ParentClass = Cast(LooseParent); + UPackage* UserParentPackage = WBG_ParentClass->GetPackage(); + UWidgetBlueprint* UserParentBP = Cast(UserParentPackage->FindAssetInPackage()); + UWidgetTree* UserParentWT = UserParentBP->WidgetTree; + + UserParentBP->OnCompiled().AddLambda( [this](UBlueprint* BP) { + if (this) + { + this->GenerateParentHierarchyFromLooseParent(); + } + }); + } +#endif } diff --git a/Project/Source/Gasa/UI/GasaUserWidget.h b/Project/Source/Gasa/UI/GasaUserWidget.h index e2158b2..7b3cbd1 100644 --- a/Project/Source/Gasa/UI/GasaUserWidget.h +++ b/Project/Source/Gasa/UI/GasaUserWidget.h @@ -9,6 +9,19 @@ class GASA_API UGasaUserWidget : public UUserWidget GENERATED_BODY() public: + UFUNCTION() + void OnLooseParentCompiled(UBlueprint* BP); + + UFUNCTION(CallInEditor, Category="Parent (Expriemental)", meta=( + ToolTip="Exprimental: This will overrite the current LooseParent widgets or create them in this user widget. Beware it will be destructive changes")) + void GenerateParentHierarchyFromLooseParent(); + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Parent (Expriemental)") + bool bUpdateOnParentCompile = false; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Parent (Expriemental)") + TSubclassOf LooseParent; + UPROPERTY(BlueprintReadOnly) TObjectPtr WidgetController; @@ -23,4 +36,13 @@ public: UFUNCTION(BlueprintImplementableEvent) void OnWidgetControllerSet(); + +#pragma region UserWidget + bool Initialize() override; + + void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; + + void NativeOnInitialized() override; + void NativePreConstruct() override; +#pragma endregion UserWidget }; diff --git a/Project/Source/Gasa/UI/GlobeProgressBar.cpp b/Project/Source/Gasa/UI/GlobeProgressBar.cpp index 10206d5..4276bd3 100644 --- a/Project/Source/Gasa/UI/GlobeProgressBar.cpp +++ b/Project/Source/Gasa/UI/GlobeProgressBar.cpp @@ -1,17 +1,70 @@ #include "GlobeProgressBar.h" #include "GasaImage.h" +#include "GasaOverlay.h" #include "GasaProgressBar.h" #include "GasaSizeBox.h" + #include "Components/OverlaySlot.h" +#include "Blueprint/WidgetBlueprintGeneratedClass.h" +#include "Blueprint/WidgetTree.h" +#include "Extensions/WidgetBlueprintGeneratedClassExtension.h" + +#if WITH_EDITOR +#include "WidgetBlueprint.h" +#include "Kismet2/BlueprintEditorUtils.h" +#endif + +using namespace Gasa; // UGlobeProgressBar::UGlobeProgressBar(FObjectInitializer const& ObjectInitializer) // { // } -void UGlobeProgressBar::SetBackgroundStyle(FSlateBrush brush) +void UGlobeProgressBar::GenerateDesignerWidgetTemplate() { - BG->SetBrush( brush ); +#if WITH_EDITOR + UWidgetBlueprintGeneratedClass* WBG_Class = Cast(GetClass()); + + UPackage* Package = WBG_Class->GetPackage(); + UWidgetBlueprint* AssetBP = Cast(Package->FindAssetInPackage()); + UWidgetTree* WT = AssetBP->WidgetTree; + + UWidget* AssetRoot = AssetBP->WidgetTree->RootWidget; + + UGasaSizeBox* Asset_SB = WT->FindWidget("Root"); + UGasaOverlay* Asset_Overlay = WT->FindWidget("Overlay"); + UGasaImage* Asset_Bezel = WT->FindWidget("Bezel"); + UGasaImage* Asset_Glass = WT->FindWidget("Glass"); + UGasaProgressBar* Asset_Bar = WT->FindWidget("Bar"); + if (Root_SB == nullptr) + Asset_SB = WT->ConstructWidget(UGasaSizeBox::StaticClass(), FName("Root_SB")); + if (Overlay == nullptr) + Asset_Overlay = WT->ConstructWidget(UGasaOverlay::StaticClass(), FName("Overlay")); + if (Bezel == nullptr) + Asset_Bezel = WT->ConstructWidget(UGasaImage::StaticClass(), FName("Bezel")); + if (Glass == nullptr) + Asset_Glass = WT->ConstructWidget(UGasaImage::StaticClass(), FName("Glass")); + if (Bar == nullptr) + Asset_Bar = WT->ConstructWidget(UGasaProgressBar::StaticClass(), FName("Bar")); + + WT->RootWidget = Asset_SB; + Asset_SB->ClearChildren(); + Asset_Overlay->ClearChildren(); + Asset_SB->AddChild(Asset_Overlay); + Asset_Overlay->AddChild(Asset_Bezel); + Asset_Overlay->AddChild(Asset_Glass); + Asset_Overlay->AddChild(Asset_Bar); + + AssetBP->Modify(); + FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(AssetBP); +#endif +} + +#pragma region Bindings +void UGlobeProgressBar::SetBezelStyle(FSlateBrush brush) +{ + Bezel->SetBrush( brush ); } void UGlobeProgressBar::SetBarPadding(FMargin margin ) @@ -38,24 +91,52 @@ void UGlobeProgressBar::SetGlassStyle(FSlateBrush brush) void UGlobeProgressBar::SetSize(float width, float height) { - SizeBox_Root->SetWidthOverride( width ); - SizeBox_Root->SetHeightOverride( height ); + Root_SB->SetWidthOverride( width ); + Root_SB->SetHeightOverride( height ); +} +#pragma endregion Bindings + +#pragma region Widget +void UGlobeProgressBar::SynchronizeProperties() +{ + Super::SynchronizeProperties(); } -#if 0 -void UGlobeProgressBar::UpdateSize() +void UGlobeProgressBar::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { - + Super::PostEditChangeProperty(PropertyChangedEvent); } - -void UGlobeProgressBar::UpdateBackground() -{ -} -#endif +#pragma endregion Widget #pragma region UserWidget void UGlobeProgressBar::NativePreConstruct() { - Super::NativePreConstruct(); + // Super::NativePreConstruct(); - Inlined + LLM_SCOPE_BYTAG(UI_UMG); + const bool bIsDesignTime = IsDesignTime(); + + UWidgetBlueprintGeneratedClass* WBG_Class = Cast(GetClass()); + if (WBG_Class) + { + WBG_Class->ForEachExtension([this, bIsDesignTime](UWidgetBlueprintGeneratedClassExtension* Extension) + { + Extension->PreConstruct(this, bIsDesignTime); + }); + } + + DesiredFocusWidget.Resolve(WidgetTree); + + // Blueprint Callback + PreConstruct(bIsDesignTime); +} + +void UGlobeProgressBar::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); +} + +void UGlobeProgressBar::Serialize(FStructuredArchive::FRecord Record) +{ + Super::Serialize(Record); } #pragma endregion UserWidget diff --git a/Project/Source/Gasa/UI/GlobeProgressBar.h b/Project/Source/Gasa/UI/GlobeProgressBar.h index 0549c42..766e4a6 100644 --- a/Project/Source/Gasa/UI/GlobeProgressBar.h +++ b/Project/Source/Gasa/UI/GlobeProgressBar.h @@ -11,25 +11,29 @@ class GASA_API UGlobeProgressBar : public UGasaUserWidget GENERATED_BODY() public: - UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe") - UGasaSizeBox* SizeBox_Root; - UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe") - UGasaOverlay* Overlay_Root; + // Just learning: https://benui.ca/unreal/build-widgets-in-editor/?utm_medium=social&utm_source=Discord + UFUNCTION(CallInEditor, Category="Generate Designer Widget Template") + void GenerateDesignerWidgetTemplate(); - UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe") - UGasaImage* Glass; +#pragma region Bindings + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe") + UGasaSizeBox* Root_SB; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe") + UGasaOverlay* Overlay; - UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe") - UGasaImage* BG; + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe") + UGasaImage* Bezel; - UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe") + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe") UGasaProgressBar* Bar; - // UGlobeProgressBar(FObjectInitializer const& ObjectInitializer); - + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe") + UGasaImage* Glass; + UFUNCTION(BlueprintCallable, Category="Globe") - void SetBackgroundStyle(FSlateBrush brush); + void SetBezelStyle(FSlateBrush brush); UFUNCTION(BlueprintCallable, Category="Globe") void SetBarPadding( FMargin margin ); @@ -45,16 +49,22 @@ public: UFUNCTION(BlueprintCallable, Category="Globe") void SetSize(float width, float height); - -#if 0 - UFUNCTION(BlueprintCallable, Category="Globe") - void UpdateSize(); +#pragma endregion Bindings - UFUNCTION(BlueprintCallable, Category="Globe") - void UpdateBackground(); -#endif + // UGlobeProgressBar(FObjectInitializer const& ObjectInitializer); + +#pragma region Widget + void SynchronizeProperties() override; +#pragma endregion Widget + + void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; #pragma region UserWidget void NativePreConstruct() override; #pragma endregion UserWidget + +#pragma region Object + void Serialize(FArchive& Ar) override; + void Serialize(FStructuredArchive::FRecord Record) override; +#pragma endregion Object }; diff --git a/Project/Source/Gasa/UI/UI_HostWidget.cpp b/Project/Source/Gasa/UI/UI_HostWidget.cpp new file mode 100644 index 0000000..98d05ff --- /dev/null +++ b/Project/Source/Gasa/UI/UI_HostWidget.cpp @@ -0,0 +1 @@ +#include "UI_HostWidget.h" diff --git a/Project/Source/Gasa/UI/UI_HostWidget.h b/Project/Source/Gasa/UI/UI_HostWidget.h new file mode 100644 index 0000000..ca8dd31 --- /dev/null +++ b/Project/Source/Gasa/UI/UI_HostWidget.h @@ -0,0 +1,13 @@ +#pragma once + +#include "GasaUserWidget.h" + +#include "UI_HostWidget.generated.h" + +UCLASS() +class GASA_API UUI_HostWidget : public UGasaUserWidget +{ + GENERATED_BODY() +public: +// #pragma region +}; diff --git a/Project/Source/Gasa/UI/WidgetController.h b/Project/Source/Gasa/UI/WidgetController.h index 399537d..fcddb47 100644 --- a/Project/Source/Gasa/UI/WidgetController.h +++ b/Project/Source/Gasa/UI/WidgetController.h @@ -4,7 +4,7 @@ #include "WidgetController.generated.h" UCLASS(BlueprintType) -class GASA_API UWdgetController : public UObject +class GASA_API UWidgetController : public UObject { GENERATED_BODY() public: diff --git a/Project/Source/GasaEditor.Target.cs b/Project/Source/GasaEditor.Target.cs index b43742a..028878a 100644 --- a/Project/Source/GasaEditor.Target.cs +++ b/Project/Source/GasaEditor.Target.cs @@ -1,3 +1,7 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime; using BuildSettingsVersion = UnrealBuildTool.BuildSettingsVersion; using TargetInfo = UnrealBuildTool.TargetInfo; using TargetRules = UnrealBuildTool.TargetRules; @@ -11,10 +15,15 @@ public class GasaEditorTarget : TargetRules DefaultBuildSettings = BuildSettingsVersion.Latest; - // bUseUnityBuild = false; + bUseUnityBuild = true; // bUseXGEController = false; ExtraModuleNames.Add("Gasa"); ExtraModuleNames.Add("GasaEditor"); + + DirectoryInfo di_uproject = new DirectoryInfo(Path.GetDirectoryName(ProjectFile.ToString())).Parent; + string path_uproject = di_uproject.FullName; + string path_scripts = Path.Combine(path_uproject, "scripts"); + string ps_gen_pass_gasa = Path.Combine(path_scripts, "gen_pass_gasa.ps1"); } } diff --git a/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.cpp b/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.cpp new file mode 100644 index 0000000..99f8008 --- /dev/null +++ b/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.cpp @@ -0,0 +1,171 @@ +#include "GlobeProgressBarDetails.h" + +#include "BaseWidgetBlueprint.h" +#include "BlueprintEditor.h" +#include "GasaEditorCommon.h" +#include "DetailCategoryBuilder.h" +#include "DetailLayoutBuilder.h" +#include "DetailWidgetRow.h" +#include "PropertyCustomizationHelpers.h" +#include "Blueprint/WidgetBlueprintGeneratedClass.h" +#include "Blueprint/WidgetTree.h" +#include "Components/ProgressBar.h" +#include "Gasa/UI/GlobeProgressBar.h" +#include "Kismet2/BlueprintEditorUtils.h" +#include "UI/GasaProgressBar.h" + +UE_DISABLE_OPTIMIZATION +void FGlobeProgressBarDetails::CustomizeDetails(IDetailLayoutBuilder& LayoutBuilder) +{ + IDetailCategoryBuilder& GlobeCategory = LayoutBuilder.EditCategory("Globe"); + + UObject* GlobeBar = nullptr; + UGlobeProgressBar* Globe = nullptr; + for (TWeakObjectPtr Object : LayoutBuilder.GetSelectedObjects()) + { + if ( ! Object.IsValid()) + return; + + Globe = Cast(Object.Get()); + if (Globe) + break; + } + + if (Globe && Globe->Bar) + { + auto StyleFillImage = Globe->Bar->GetWidgetStyle().FillImage.GetResourceObject(); + Thumbnail = MakeShareable(new FAssetThumbnail(FAssetData(StyleFillImage), 64, 64, LayoutBuilder.GetThumbnailPool())); + } + + TSharedPtr + ProgressBarStyle = LayoutBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UGlobeProgressBar, Bar), UGlobeProgressBar::StaticClass()); + ProgressBarStyle->GetValue(GlobeBar); + if (ProgressBarStyle && ! ProgressBarStyle->IsValidHandle()) + return; + + // This can't be done, UE widget parenting forces the parent widget's hierarchy to be immutable at 'design time'. + // This is because a proper clone of the UWidgetBlueprintGeneratedClass parent's widget tree is not done. + // Instead... I don't even know what they are even doing with the widget tree because somehow they still have a unique widget tree + // for at least the child widget. + // All code paths related to this are not navigable in a reasonable amount of time. + // So I don't even know why this failure point exist architecturally... +#if 0 + // TSharedPtr WidgetStyle = ProgressBarStyleHandle->GetChildHandle("WidgetStyle"); + // if ( ! WidgetStyle.IsValid()) + // return; + IDetailPropertyRow& ProgressBarRow = LayoutBuilder.AddPropertyToCategory(ProgressBarStyle); + + FDetailWidgetRow& RowWidget = ProgressBarRow.CustomWidget(); + { + FDetailWidgetDecl& RowNameWidget = RowWidget.NameContent(); + { + TSharedRef + TextBlock = SNew(STextBlock); + TextBlock->SetText(FText::FromString(TEXT("Bar Fill Material"))); + TextBlock->SetFont(LayoutBuilder.GetDetailFont()); + RowNameWidget.Widget = TextBlock; + } + + FDetailWidgetDecl& RowValueWidget = RowWidget.ValueContent(); + TSharedRef HBox = SNew(SHorizontalBox); + { + SHorizontalBox::FSlot::FSlotArguments ThumbnailSlot = SHorizontalBox::Slot(); + { + TSharedRef ThumbnailBox = SNew(SBox); + ThumbnailBox->SetWidthOverride(64); + ThumbnailBox->SetHeightOverride(64); + + if ( Thumbnail.IsValid() ) + ThumbnailBox->SetContent( Thumbnail->MakeThumbnailWidget()); + else + ThumbnailBox->SetContent( SNullWidget::NullWidget ); + + ThumbnailSlot.AutoWidth(); + ThumbnailSlot.AttachWidget( ThumbnailBox ); + } + + SHorizontalBox::FSlot::FSlotArguments DropDownSlot = SHorizontalBox::Slot(); + { + TSharedRef EntryBox = SNew(SObjectPropertyEntryBox); + { + SObjectPropertyEntryBox::FArguments Args; + Args.PropertyHandle(ProgressBarStyle); + Args.AllowClear(false); + // Args.OnShouldFilterAsset_Lambda( [&](FAssetData const& Asset) -> bool + // { + // FString const AssetPath = Asset.ObjectPath.ToString(); + // // Add conditional filters here + // return true; + // }); + Args.DisplayThumbnail(false); + Args.OnObjectChanged_Lambda( [this, Globe, &ProgressBarStyle, &LayoutBuilder](FAssetData const& Asset) + { + if ( ! Asset.IsValid() || ! Thumbnail.IsValid() || ! Globe || ! Globe->Bar ) + return; + + FProgressBarStyle + Style = Globe->Bar->GetWidgetStyle(); + Style.FillImage.SetResourceObject(Asset.GetAsset()); + + // Get the Blueprint that owns this widget and mark it as modified + UBaseWidgetBlueprint* GlobeBP = Cast(Globe->WidgetGeneratedBy); + if (GlobeBP != nullptr) + { + GlobeBP->Modify(); + UObject* CDO = GlobeBP->GeneratedClass->GetDefaultObject(); + UGlobeProgressBar* GlobeCDO = Cast(CDO); + + UWidget* PossibleWidget = Cast(GlobeBP)->WidgetTree->FindWidget("Bar"); + if (PossibleWidget) + { + UGasaProgressBar* BarWidget = Cast(PossibleWidget); + BarWidget->SetWidgetStyle(Style); + GlobeBP->MarkPackageDirty(); + } + else // Its parent is it. + { + UWidgetBlueprintGeneratedClass* Parent = Cast(GlobeBP->ParentClass); + UPackage* Pkg = Parent->GetOuterUPackage(); + + PossibleWidget = Parent->GetWidgetTreeArchetype()->FindWidget("Bar"); + if (PossibleWidget) + { + GlobeCDO->Bar = GlobeCDO->WidgetTree->ConstructWidget( PossibleWidget->GetClass(), "Bar" ); + Globe->Bar = GlobeCDO->Bar; + GlobeCDO->Modify(); + GlobeCDO->MarkPackageDirty(); + } + } + } + + Globe->SetBarStyle(Style); + Globe->Bar->Modify(); + Globe->Modify(); + + Thumbnail->SetAsset(Asset); + Thumbnail->RefreshThumbnail(); + }); + // Args.CustomResetToDefault(FResetToDefaultOverride::Hide()); + Args.DisplayBrowse(true); + EntryBox->Construct(Args); + } + + DropDownSlot.AutoWidth(); + DropDownSlot.AttachWidget(EntryBox); + } + + SHorizontalBox::FArguments Args = SHorizontalBox::FArguments(); + Args.operator+(ThumbnailSlot); + Args.operator+(DropDownSlot); + HBox->Construct(Args); + RowValueWidget.Widget = HBox; + } + } +#endif +} + +bool FGlobeProgressBarDetails::CheckAsset(FAssetData const& Asset) +{ + return true; +} +UE_ENABLE_OPTIMIZATION diff --git a/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.h b/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.h new file mode 100644 index 0000000..c3facf8 --- /dev/null +++ b/Project/Source/GasaEditor/EditorDetails/GlobeProgressBarDetails.h @@ -0,0 +1,14 @@ +#pragma once +#include "IDetailCustomization.h" + + +class FGlobeProgressBarDetails : public IDetailCustomization +{ +public: + static TSharedRef MakeInstance() { return MakeShareable(new FGlobeProgressBarDetails); } + + void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; + + static bool CheckAsset(FAssetData const& Asset); + TSharedPtr Thumbnail; +}; diff --git a/Project/Source/GasaEditor/GasaEditor.Build.cs b/Project/Source/GasaEditor/GasaEditor.Build.cs index d4fde14..2e45960 100644 --- a/Project/Source/GasaEditor/GasaEditor.Build.cs +++ b/Project/Source/GasaEditor/GasaEditor.Build.cs @@ -8,12 +8,22 @@ public class GasaEditor : ModuleRules #region Engine PrivateIncludePathModuleNames.AddRange(new string[] { "Core", + "CoreUObject", + "Engine", }); PrivateDependencyModuleNames.AddRange(new string[] { - "Core", + "Core", + "Engine", + "CoreUObject", + "PropertyEditor", + "SlateCore", + "Slate", + "UMG", + "UnrealEd", }); #endregion Engine - PublicIncludePathModuleNames.Add("Gasa"); + PublicIncludePaths.Add("GasaEditor"); + PrivateDependencyModuleNames.Add("Gasa"); } } diff --git a/Project/Source/GasaEditor/GasaEditorCommon.cpp b/Project/Source/GasaEditor/GasaEditorCommon.cpp new file mode 100644 index 0000000..cb0ea1e --- /dev/null +++ b/Project/Source/GasaEditor/GasaEditorCommon.cpp @@ -0,0 +1,3 @@ +#include "GasaEditorCommon.h" + +DEFINE_LOG_CATEGORY(LogGasaEditor); diff --git a/Project/Source/GasaEditor/GasaEditorCommon.h b/Project/Source/GasaEditor/GasaEditorCommon.h new file mode 100644 index 0000000..5b65bdc --- /dev/null +++ b/Project/Source/GasaEditor/GasaEditorCommon.h @@ -0,0 +1,68 @@ + +#pragma once + +#include "CoreMinimal.h" +#include "Gasa/GasaCommon.h" + +#pragma region Engine Forwards +#pragma endregion Engine Forwards + +#pragma region Engine Plugin Forwards +#pragma endregion Engine Plugin Forwards + +// Gasa Editor + +#pragma region Forwards +#pragma endregion Forwards + +#pragma region Logging +DECLARE_LOG_CATEGORY_EXTERN(LogGasaEditor, Log, All); + +namespace Gasa +{ + using ELogV = EGasaVerbosity; + + //◞ ‸ ◟// + // Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now) + inline + void LogEditor( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log + , FLogCategoryBase& Category = LogGasaEditor + , bool DumpStack = false + , int32 Line = __builtin_LINE() + , const ANSICHAR* File = __builtin_FILE() + , const ANSICHAR* Func = __builtin_FUNCTION() ) + { + #if !UE_BUILD_SHIPPING && !NO_LOGGING + ELogVerbosity::Type EngineVerbosity = (ELogVerbosity::Type) Verbosity; + + static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic; + static UE::Logging::Private::FStaticBasicLogRecord + LOG_Static(TEXT("%80s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic); + + if ((EngineVerbosity & ELogVerbosity::VerbosityMask) <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY) + { + if ((EngineVerbosity & ELogVerbosity::VerbosityMask) <= Category.GetVerbosity()) + { + if ( ! Category.IsSuppressed(EngineVerbosity)) + { + if (DumpStack) + FDebug::DumpStackTraceToLog(EngineVerbosity); + BasicLog(Category, &LOG_Static, *Message, File, Func, Line); + } + } + } + #endif + } +} + +#define GasaEd_Fatal(Message) UE_LOG( LogGasaEditor, Fatal, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_FILE(), __func__, __builtin_LINE() ); +#define GasaEd_Error(Message) UE_LOG( LogGasaEditor, Error, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GasaEd_Warning(Message) UE_LOG( LogGasaEditor, Warning, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GasaEd_Display(Message) UE_LOG( LogGasaEditor, Display, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GasaEd_Log(Message) UE_LOG( LogGasaEditor, Log, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GasaEd_Verbose(Message) UE_LOG( LogGasaEditor, Verbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#define GasaEd_VeryVerbose(Message) UE_LOG( LogGasaEditor, VeryVerbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() ); +#pragma endregion Logging + +#pragma region Timing +#pragma endregion Timing diff --git a/Project/Source/GasaEditor/GasaEditorModule.cpp b/Project/Source/GasaEditor/GasaEditorModule.cpp index b9443b7..dd2a068 100644 --- a/Project/Source/GasaEditor/GasaEditorModule.cpp +++ b/Project/Source/GasaEditor/GasaEditorModule.cpp @@ -1,14 +1,25 @@ #include "GasaEditorModule.h" +#include "EditorDetails/GlobeProgressBarDetails.h" +#include "UI/GlobeProgressBar.h" + IMPLEMENT_PRIMARY_GAME_MODULE(FGasaEditorModule, GasaEditor, GasaEditor); void FGasaEditorModule::StartupModule() { + FPropertyEditorModule& PropertyEditor = FModuleManager::LoadModuleChecked("PropertyEditor"); + PropertyEditor.RegisterCustomClassLayout( UGlobeProgressBar::StaticClass()->GetFName() + , FOnGetDetailCustomizationInstance::CreateStatic(& FGlobeProgressBarDetails::MakeInstance) + ); } void FGasaEditorModule::ShutdownModule() { - + if (FModuleManager::Get().IsModuleLoaded("PropertyEditor")) + { + FPropertyEditorModule& PropertyEditor = FModuleManager::GetModuleChecked("PropertyEditor"); + PropertyEditor.UnregisterCustomClassLayout(UGlobeProgressBar::StaticClass()->GetFName()); + } } \ No newline at end of file diff --git a/Project/Source/GasaGen/GasaGen.cpp b/Project/Source/GasaGen/GasaGen.cpp index 5853b66..83b03c8 100644 --- a/Project/Source/GasaGen/GasaGen.cpp +++ b/Project/Source/GasaGen/GasaGen.cpp @@ -5,109 +5,84 @@ #define GEN_IMPLEMENTATION #include "gen.cpp" #include "gen.builder.cpp" -#include "gen.scanner.hpp" +// #include "gen.scanner.hpp" using namespace gen; +#ifdef GEN_SYSTEM_WINDOWS + #include +#endif + #include "GasaGenCommon.cpp" #include "GasaGen_ue_parse_testing.cpp" #include "GasaGen_UGasaAttributeSet.cpp" #include "GasaGen_ChangeBPActionMenu.cpp" +#include "GasaGen_DevOptionsCache.cpp" int gen_main() { gen::init(); - log_fmt("Generating code for the Gasa module"); + log_fmt("Generating code for the Gasa module\n"); // Initialize Globals - umeta_uclass = code_str( UCLASS() ); - umeta_generated_body = code_str( GENERATED_BODY() ); - gasa_api = code_str( GASA_API ); + { + UHT_UCLASS = code_str( UCLASS() ); + UHT_UPROPERTY = code_str( UPROPERTY() ); + UHT_USTRUCT = code_str( USTRUCT() ); + UHT_GENERATED_BODY = code_str( GENERATED_BODY()\n ); + UModule_GASA_API = code_str( GASA_API ); + } - StrC str_GENERATED_BODY = txt("GENERATED_BODY("); - StrC str_GENERATED_UCLASS_BODY = txt("GENERATED_UCLASS_BODY("); - StrC str_PROPERTY_BINDING_IMPLEMENTATION = txt("PROPERTY_BINDING_IMPLEMENTATION("); - StrC str_UCLASS = txt("UCLASS("); - StrC str_UFUNCTION = txt("UFUNCTION("); - StrC str_UPROPERTY = txt("UPROPERTY("); - StrC str_DECLARE_LOG_CATEGORY_EXTERN = txt("DECLARE_LOG_CATEGORY_EXTERN("); - StrC str_ENUM_CLASS_FLAGS = txt("ENUM_CLASS_FLAGS("); - StrC str_DECLARE_CLASS = txt("DECLARE_CLASS("); - StrC str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL("); - StrC str_TEXT = txt("TEXT("); - StrC str_DECLARE_MULTICAST_DELEGATE_OneParam = txt("DECLARE_MULTICAST_DELEGATE_OneParam("); - StrC str_DECLARE_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_MULTICAST_DELEGATE_TwoParams("); - StrC str_DECLARE_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams("); - StrC str_DECLARE_DELEGATE_RetVal_OneParam = txt("DECLARE_DELEGATE_RetVal_OneParam("); - StrC str_DECLARE_FUNCTION = txt("DECLARE_FUNCTION("); - StrC str_RESULT_DECL = txt("RESULT_DECL"); - StrC str_FORCEINLINE = txt("FORCEINLINE"); - StrC str_UENUM = txt("UENUM("); - StrC str_UMETA = txt("UMETA("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams("); - StrC str_DECLARE_DELEGATE_SixParams = txt("DECLARE_DELEGATE_SixParams("); - StrC str_DECLARE_EVENT_TwoParams = txt("DECLARE_EVENT_TwoParams("); - StrC str_DECLARE_DELEGATE_RetVal_ThreeParams = txt("DECLARE_DELEGATE_RetVal_ThreeParams("); - StrC str_PRAGMA_DISABLE_DEPRECATION_WARNINGS = txt("PRAGMA_DISABLE_DEPRECATION_WARNINGS"); - StrC str_PRAGMA_ENABLE_DEPRECATION_WARNINGS = txt("PRAGMA_ENABLE_DEPRECATION_WARNINGS"); - StrC str_DEFINE_ACTORDESC_TYPE = txt("DEFINE_ACTORDESC_TYPE("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams("); - StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam("); - StrC str_UPARAM = txt("UPARAM("); - StrC str_FORCEINLINE_DEBUGGABLE = txt("FORCEINLINE_DEBUGGABLE"); - StrC str_DECLARE_EVENT_ThreeParams = txt("DECLARE_EVENT_ThreeParams("); - StrC str_USTRUCT = txt("USTRUCT("); - StrC str_GENERATED_USTRUCT_BODY = txt("GENERATED_USTRUCT_BODY("); - StrC str_SLATE_BEGIN_ARGS = txt("SLATE_BEGIN_ARGS("); - StrC str_SLATE_END_ARGS = txt("SLATE_END_ARGS("); - - PreprocessorDefines.append( get_cached_string(str_GENERATED_BODY)); - PreprocessorDefines.append( get_cached_string(str_GENERATED_UCLASS_BODY)); - PreprocessorDefines.append( get_cached_string(str_PROPERTY_BINDING_IMPLEMENTATION)); - PreprocessorDefines.append( get_cached_string(str_UCLASS)); - PreprocessorDefines.append( get_cached_string(str_UFUNCTION)); - PreprocessorDefines.append( get_cached_string(str_UPROPERTY)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_LOG_CATEGORY_EXTERN)); - PreprocessorDefines.append( get_cached_string(str_ENUM_CLASS_FLAGS)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_CLASS)); - PreprocessorDefines.append( get_cached_string(str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL)); - PreprocessorDefines.append( get_cached_string(str_TEXT)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_OneParam)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_TwoParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_ThreeParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_OneParam)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_FUNCTION)); - PreprocessorDefines.append( get_cached_string(str_RESULT_DECL)); - PreprocessorDefines.append( get_cached_string(str_FORCEINLINE)); - PreprocessorDefines.append( get_cached_string(str_UENUM)); - PreprocessorDefines.append( get_cached_string(str_UMETA)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_SixParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_TwoParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_ThreeParams)); - PreprocessorDefines.append( get_cached_string(str_PRAGMA_DISABLE_DEPRECATION_WARNINGS)); - PreprocessorDefines.append( get_cached_string(str_PRAGMA_ENABLE_DEPRECATION_WARNINGS)); - PreprocessorDefines.append( get_cached_string(str_DEFINE_ACTORDESC_TYPE)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam)); - PreprocessorDefines.append( get_cached_string(str_UPARAM)); - PreprocessorDefines.append( get_cached_string(str_FORCEINLINE_DEBUGGABLE)); - PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_ThreeParams)); - PreprocessorDefines.append( get_cached_string(str_USTRUCT)); - PreprocessorDefines.append( get_cached_string(str_GENERATED_USTRUCT_BODY)); - PreprocessorDefines.append( get_cached_string(str_SLATE_BEGIN_ARGS)); - PreprocessorDefines.append( get_cached_string(str_SLATE_END_ARGS)); - - // ue_parse_testing(); - - StrC str_gasa_api = txt("GASA_API"); + // Populate Defines + { + PreprocessorDefines.append( get_cached_string(str_DECLARE_CLASS)); + 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_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)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_ThreeParams)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_TwoParams)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_FUNCTION)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_LOG_CATEGORY_EXTERN)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_OneParam)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_ThreeParams)); + PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_TwoParams)); + PreprocessorDefines.append( get_cached_string(str_DEFINE_ACTORDESC_TYPE)); + PreprocessorDefines.append( get_cached_string(str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL)); + PreprocessorDefines.append( get_cached_string(str_ENUM_CLASS_FLAGS)); + PreprocessorDefines.append( get_cached_string(str_FORCEINLINE_DEBUGGABLE)); + PreprocessorDefines.append( get_cached_string(str_FORCEINLINE)); + PreprocessorDefines.append( get_cached_string(str_GENERATED_BODY)); + PreprocessorDefines.append( get_cached_string(str_GENERATED_UCLASS_BODY)); + PreprocessorDefines.append( get_cached_string(str_GENERATED_USTRUCT_BODY)); + PreprocessorDefines.append( get_cached_string(str_PRAGMA_DISABLE_DEPRECATION_WARNINGS)); + PreprocessorDefines.append( get_cached_string(str_PRAGMA_ENABLE_DEPRECATION_WARNINGS)); + PreprocessorDefines.append( get_cached_string(str_PROPERTY_BINDING_IMPLEMENTATION)); + PreprocessorDefines.append( get_cached_string(str_RESULT_DECL)); + PreprocessorDefines.append( get_cached_string(str_SLATE_BEGIN_ARGS)); + PreprocessorDefines.append( get_cached_string(str_SLATE_END_ARGS)); + PreprocessorDefines.append( get_cached_string(str_TEXT)); + PreprocessorDefines.append( get_cached_string(str_UCLASS)); + PreprocessorDefines.append( get_cached_string(str_UENUM)); + PreprocessorDefines.append( get_cached_string(str_UFUNCTION)); + PreprocessorDefines.append( get_cached_string(str_UMETA)); + PreprocessorDefines.append( get_cached_string(str_UPARAM)); + PreprocessorDefines.append( get_cached_string(str_UPROPERTY)); + PreprocessorDefines.append( get_cached_string(str_USTRUCT)); + } gen_UGasaAttributeSet(); - swap_SBlueprintActionMenu_Construct(); + gen_FGasaDevOptionsCache(); + + // One offs + if (0) + { + ue_parse_testing(); + swap_SBlueprintActionMenu_Construct(); + } return 0; } diff --git a/Project/Source/GasaGen/GasaGenCommon.cpp b/Project/Source/GasaGen/GasaGenCommon.cpp index 691409f..a606e06 100644 --- a/Project/Source/GasaGen/GasaGenCommon.cpp +++ b/Project/Source/GasaGen/GasaGenCommon.cpp @@ -1,13 +1,95 @@ -#pragma once +// Used in the GasaGen.cpp translation unit +#if GASA_INTELLISENSE_DIRECTIVES +#pragma once +#include "gen.hpp" +#include "GasaGenCommon.cpp" +using namespace gen; +#endif // Program assumes its working directory is the project -#define path_config "./Source/Config/" -#define path_module_gasa "./Source/Gasa/" +#define path_root "" +#define path_project path_root "Project/" +#define path_source path_project "Source/" +#define path_config path_source "Config/" +#define path_module_gasa path_source "Gasa/" #define path_gasa_ability_system path_module_gasa "AbilitySystem/" +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_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("); +constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam("); +constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams("); +constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams("); +constexpr StrC str_DECLARE_EVENT_ThreeParams = txt("DECLARE_EVENT_ThreeParams("); +constexpr StrC str_DECLARE_EVENT_TwoParams = txt("DECLARE_EVENT_TwoParams("); +constexpr StrC str_DECLARE_FUNCTION = txt("DECLARE_FUNCTION("); +constexpr StrC str_DECLARE_LOG_CATEGORY_EXTERN = txt("DECLARE_LOG_CATEGORY_EXTERN("); +constexpr StrC str_DECLARE_MULTICAST_DELEGATE_OneParam = txt("DECLARE_MULTICAST_DELEGATE_OneParam("); +constexpr StrC str_DECLARE_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams("); +constexpr StrC str_DECLARE_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_MULTICAST_DELEGATE_TwoParams("); +constexpr StrC str_DEFINE_ACTORDESC_TYPE = txt("DEFINE_ACTORDESC_TYPE("); +constexpr StrC str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL("); +constexpr StrC str_ENUM_CLASS_FLAGS = txt("ENUM_CLASS_FLAGS("); +constexpr StrC str_FORCEINLINE = txt("FORCEINLINE"); +constexpr StrC str_FORCEINLINE_DEBUGGABLE = txt("FORCEINLINE_DEBUGGABLE"); +constexpr StrC str_GENERATED_BODY = txt("GENERATED_BODY("); +constexpr StrC str_GENERATED_UCLASS_BODY = txt("GENERATED_UCLASS_BODY("); +constexpr StrC str_GENERATED_USTRUCT_BODY = txt("GENERATED_USTRUCT_BODY("); +constexpr StrC str_PRAGMA_DISABLE_DEPRECATION_WARNINGS = txt("PRAGMA_DISABLE_DEPRECATION_WARNINGS"); +constexpr StrC str_PRAGMA_ENABLE_DEPRECATION_WARNINGS = txt("PRAGMA_ENABLE_DEPRECATION_WARNINGS"); +constexpr StrC str_PROPERTY_BINDING_IMPLEMENTATION = txt("PROPERTY_BINDING_IMPLEMENTATION("); +constexpr StrC str_RESULT_DECL = txt("RESULT_DECL"); +constexpr StrC str_SLATE_BEGIN_ARGS = txt("SLATE_BEGIN_ARGS("); +constexpr StrC str_SLATE_END_ARGS = txt("SLATE_END_ARGS("); +constexpr StrC str_TEXT = txt("TEXT("); +constexpr StrC str_UCLASS = txt("UCLASS("); +constexpr StrC str_UENUM = txt("UENUM("); +constexpr StrC str_UFUNCTION = txt("UFUNCTION("); +constexpr StrC str_UMETA = txt("UMETA("); +constexpr StrC str_UPARAM = txt("UPARAM("); +constexpr StrC str_UPROPERTY = txt("UPROPERTY("); +constexpr StrC str_USTRUCT = txt("USTRUCT("); + +constexpr StrC str_GASA_API = txt("GASA_API"); + #pragma region Globals // These Code objects are created before anything else after gencpp does its initializatioon -global Code umeta_uclass; -global Code umeta_generated_body; -global Code gasa_api; +global Code UHT_GENERATED_BODY; +global Code UHT_UCLASS; +global Code UHT_UPROPERTY; +global Code UHT_USTRUCT; +global Code UModule_GASA_API; #pragma endregion Globals + +inline +CodeBody parse_file( char const* path ) { + FileContents content = file_read_contents( GlobalAllocator, true, path ); + CodeBody code = parse_global_body( StrC { content.size, (char const*)content.data }); + return code; +} + +inline +void format_file( char const* path ) +{ + // Need to execute clang format on the generated file to get it to match the original. + #define clang_format "clang-format " + #define cf_format_inplace "-i " + #define cf_style "-style=file:" "./scripts/.clang-format " + #define cf_verbose "-verbose " + String command = String::make( GlobalAllocator, clang_format ); + command.append( cf_format_inplace ); + command.append( cf_style ); + command.append( cf_verbose ); + command.append( path ); + log_fmt("\tRunning clang-format on file:\n"); + system( command ); + log_fmt("\tclang-format finished reformatting.\n"); + #undef cf_cmd + #undef cf_format_inplace + #undef cf_style + #undef cf_verbse +} diff --git a/Project/Source/GasaGen/GasaGen_ChangeBPActionMenu.cpp b/Project/Source/GasaGen/GasaGen_ChangeBPActionMenu.cpp index 43ebf2c..6501b8c 100644 --- a/Project/Source/GasaGen/GasaGen_ChangeBPActionMenu.cpp +++ b/Project/Source/GasaGen/GasaGen_ChangeBPActionMenu.cpp @@ -1,3 +1,12 @@ +// Used in the GasaGen.cpp translation unit +#if GASA_INTELLISENSE_DIRECTIVES +#pragma once +#define GEN_EXPOSE_BACKEND +#include "gen.hpp" +#include "gen.builder.hpp" +#include "GasaGenCommon.cpp" +#endif + constexpr StrC SBlueprintActionMenu_Construct_Replacement = txt(R"( void SBlueprintActionMenu::Construct( const FArguments& InArgs, TSharedPtr InEditor ) { @@ -255,19 +264,22 @@ void swap_SBlueprintActionMenu_Construct() using namespace ECode; case Function: CodeFn function_def = code.cast(); - log_fmt("%S\n", function_def->Name); if ( String::are_equal(function_def->Name, signature_to_change->Name) && function_def->Params.is_equal(signature_to_change->Params)) { code = parse_function( SBlueprintActionMenu_Construct_Replacement ); + log_fmt("Swapped: %S", function_def->Name); } break; } changed_SBlueprintActionMenu.append(code); } + log_fmt("\n"); Builder SBlueprintActionMenu_Changed = Builder::open(path_SBlueprintActionMenuCpp); + SBlueprintActionMenu_Changed.print( def_comment(txt("This file was regenerated by GasaGen.cpp"))); SBlueprintActionMenu_Changed.print(changed_SBlueprintActionMenu); SBlueprintActionMenu_Changed.write(); -} \ No newline at end of file + format_file(path_SBlueprintActionMenuCpp); +} diff --git a/Project/Source/GasaGen/GasaGen_DevOptionsCache.cpp b/Project/Source/GasaGen/GasaGen_DevOptionsCache.cpp new file mode 100644 index 0000000..f99c0c1 --- /dev/null +++ b/Project/Source/GasaGen/GasaGen_DevOptionsCache.cpp @@ -0,0 +1,135 @@ +// Used in the GasaGen.cpp translation unit +#if GASA_INTELLISENSE_DIRECTIVES +#pragma once +#define GEN_EXPOSE_BACKEND +#include "gen.hpp" +#include "gen.builder.hpp" +#include "GasaGenCommon.cpp" +using namespace gen; +#endif + +void gen_FGasaDevOptionsCache() +{ + Array GasaDevOptions_UPROPERTIES = Array::init(GlobalAllocator); + { + CodeBody header_GasaDevOptions = parse_file( path_module_gasa "GasaDevOptions.h" ); + CodeClass UGasaDevOptions = NoCode; + for (Code entry : header_GasaDevOptions) + { + if ( entry->Type == ECode::Class && entry->Name.starts_with( txt("UGasaDevOptions")) ) + { + UGasaDevOptions = entry.cast(); + break; + } + } + for (Code member = UGasaDevOptions->Body.begin(); member != UGasaDevOptions->Body.end(); ++ member) + { + if ( member->Type == ECode::Untyped && member->Name.starts_with(str_UPROPERTY) ) + ++ member; + if ( member->Type == ECode::Variable + && ( member->ValueType->Name.starts_with( txt("TSoftClassPtr")) + || member->ValueType->Name.starts_with( txt("TSoftObjectPtr")) ) + ) + GasaDevOptions_UPROPERTIES.append(member.cast()); + } + } + + CodeComment generation_notice = def_comment(txt("This was generated by GasaGen/GasaGen.cpp")); + + Builder header = Builder::open( path_module_gasa "GasaDevOptionsCache.h" ); + { + header.print( generation_notice ); + header.print( pragma_once ); + header.print( fmt_newline ); + header.print( def_include(txt("GasaDevOptionsCache.generated.h"))); + header.print( fmt_newline ); + + header.print( UHT_USTRUCT ); + CodeStruct FGasaDevOptionsCache; + { + CodeBody body = def_body(ECode::Struct_Body); + { + CodeType t_UClassPtr = parse_type(code(UClass*)); + CodeType t_UObjectPtr = parse_type(code(UObject*)); + + body.append(UHT_GENERATED_BODY); + body.append(fmt_newline); + for (CodeVar var : GasaDevOptions_UPROPERTIES) + { + if ( var->ValueType->Name.starts_with( txt("TSoftClassPtr") )) { + body.append(UHT_UPROPERTY); + body.append( def_variable(t_UClassPtr, var->Name)); + } + if ( var->ValueType->Name.starts_with( txt("TSoftObjectPtr") )) { + body.append(UHT_UPROPERTY); + body.append( def_variable(t_UObjectPtr, var->Name)); + } + } + body.append(fmt_newline); + body.append( parse_function(code( void CachedDevOptions(); ))); + } + FGasaDevOptionsCache = parse_struct( token_fmt( "body", (StrC)body.to_string(), stringize( + struct GASA_API FGasaDevOptionsCache { + + }; + ))); + } + header.print(FGasaDevOptionsCache); + header.print( fmt_newline ); + header.write(); + format_file( path_module_gasa "GasaDevOptionsCache.h" ); + } + + Builder source = Builder::open( path_module_gasa "GasaDevOptionsCache.cpp" ); + { + Array GasaDevOptions_Includes = Array::init(GlobalAllocator); + { + CodeBody source_GasaDevOptions = parse_file( path_module_gasa "GasaDevOptions.cpp"); + for ( Code entry : source_GasaDevOptions ) + { + if ( entry->Type == ECode::Preprocess_Include ) + GasaDevOptions_Includes.append( entry.cast() ); + } + } + + source.print( generation_notice ); + source.print( def_include(txt("GasaDevOptionsCache.h"))); + source.print(fmt_newline); + for ( CodeInclude include : GasaDevOptions_Includes ) { + source.print( include ); + } + source.print( parse_using(code( using namespace Gasa; ))); + source.print(fmt_newline); + + CodeBody cached_property_assignments = def_body(ECode::Function_Body); + { + cached_property_assignments.append(fmt_newline); + cached_property_assignments.append(fmt_newline); + for (CodeVar var : GasaDevOptions_UPROPERTIES) + { + Code assignment = code_fmt( "property", (StrC)var->Name, stringize( + = DevOpts-> .LoadSynchronous(); + )); + cached_property_assignments.append(assignment); + } + cached_property_assignments.append(fmt_newline); + cached_property_assignments.append(fmt_newline); + } + + CodeFn CachedDevOptions = parse_function( token_fmt( + "cached_property_assignments", (StrC)cached_property_assignments.to_string(), + stringize( + void FGasaDevOptionsCache::CachedDevOptions() + { + UGasaDevOptions* DevOpts = GetMutDevOptions(); + + + + Tag_GlobalPPV = DevOpts->Tag_GlobalPPV; + }) + )); + source.print(CachedDevOptions); + source.write(); + format_file( path_module_gasa "GasaDevOptionsCache.cpp" ); + } +} diff --git a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp index 4111e69..c775a16 100644 --- a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp +++ b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp @@ -1,4 +1,11 @@ // Used in the GasaGen.cpp translation unit +#if GASA_INTELLISENSE_DIRECTIVES +#pragma once +#define GEN_EXPOSE_BACKEND +#include "gen.hpp" +#include "gen.builder.hpp" +#include "GasaGenCommon.cpp" +#endif void def_attribute_properties ( CodeBody body, Array properties ); void def_attribute_field_on_reps ( CodeBody body, Array properties ); @@ -30,20 +37,20 @@ void gen_UGasaAttributeSet() CodeInclude Include_AbilitySystemComponent = def_include(txt("AbilitySystemComponent.h")); CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h")); - CodeAttributes api_attribute= def_attributes( gasa_api->Name); + CodeAttributes api_attribute= def_attributes( UModule_GASA_API->Name); CodeClass GasaAttributeSet = {}; { CodeBody body = def_body( CodeT::Class_Body ); { - body.append( umeta_generated_body); - body.append( fmt_newline); + body.append( UHT_GENERATED_BODY); body.append( access_public ); def_attribute_properties( body, attribute_fields); body.append(fmt_newline); body.append( def_constructor() ); + body.append(fmt_newline); def_attribute_field_on_reps( body, attribute_fields); @@ -90,11 +97,12 @@ void gen_UGasaAttributeSet() header.print( Include_AbilitySystemComponent); header.print( Include_GasaAttributeSet_Generated); header.print( fmt_newline); - header.print(umeta_uclass); + header.print( UHT_UCLASS ); header.print(GasaAttributeSet); header.print(ns_gasa); } header.write(); + format_file(path_gasa_ability_system "GasaAttributeSet.h"); } Builder source = Builder::open( path_gasa_ability_system "GasaAttributeSet.cpp" ); @@ -119,15 +127,15 @@ void gen_UGasaAttributeSet() InitMaxMana( 50.f ); } )); - body.append(constructor_for_UGasaAttributeSet ); - body.append(fmt_newline); impl_attribute_fields( body, class_name, attribute_fields); CodeFn GetLifetimeOfReplicatedProps; { CodeBody field_lifetimes = def_body( CodeT::Function_Body); + field_lifetimes.append(fmt_newline); + field_lifetimes.append(fmt_newline); for (StringCached field : attribute_fields) { field_lifetimes.append( code_fmt( "field", (StrC)field, stringize( @@ -148,6 +156,7 @@ void gen_UGasaAttributeSet() source.print(body); } source.write(); + format_file(path_gasa_ability_system "GasaAttributeSet.cpp"); } } @@ -200,12 +209,12 @@ void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array } } +#pragma push_macro("FORCEINLINE") +#undef FORCEINLINE void def_attribute_field_value_getters( CodeBody body, Array properties ) { for ( String property : properties ) { -#pragma push_macro(FORCEINLINE) -#undef FORCEINLINE body.append( code_fmt( "property", (StrC)property, stringize( FORCEINLINE float Get() const @@ -213,7 +222,6 @@ void def_attribute_field_value_getters( CodeBody body, Array prope return .GetCurrentValue(); } ))); -#pragma pop_macro(FORCEINLINE) } } @@ -267,3 +275,4 @@ void impl_attribute_fields( CodeBody body, StrC class_name, Array body.append( field_impl ); } } +#pragma pop_macro("FORCEINLINE") diff --git a/Project/Source/GasaGen/GasaGen_ue_parse_testing.cpp b/Project/Source/GasaGen/GasaGen_ue_parse_testing.cpp index 2b39e62..4721fe1 100644 --- a/Project/Source/GasaGen/GasaGen_ue_parse_testing.cpp +++ b/Project/Source/GasaGen/GasaGen_ue_parse_testing.cpp @@ -1,3 +1,12 @@ +// Used in the GasaGen.cpp translation unit +#if GASA_INTELLISENSE_DIRECTIVES +#pragma once +#define GEN_EXPOSE_BACKEND +#include "gen.hpp" +#include "gen.builder.hpp" +#include "GasaGenCommon.cpp" +#endif + void ue_parse_testing() { FileContents content; @@ -5,7 +14,7 @@ void ue_parse_testing() #define path_UProgressBar \ "C:/projects/Unreal/Surgo/UE/Engine/Source/Runtime/UMG/Public/Components/ProgressBar.h" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_UProgressBar ); CodeBody parsed_uprogressbar = parse_global_body( StrC { content.size, (char const*)content.data }); @@ -40,7 +49,7 @@ void ue_parse_testing() #define path_UObject \ R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\CoreUObject\Public\UObject\Object.h)" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_UObject ); CodeBody parsed_uobject = parse_global_body( StrC { content.size, (char const*)content.data }); @@ -78,7 +87,7 @@ void ue_parse_testing() #define path_AActor \ R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\GameFramework\Actor.h)" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_AActor ); CodeBody parsed_aactor = parse_global_body( StrC { content.size, (char const*)content.data }); @@ -112,7 +121,7 @@ void ue_parse_testing() #define path_ActorComponent \ R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\Components\ActorComponent.h)" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_ActorComponent ); CodeBody parsed_actor_component = parse_global_body( StrC { content.size, (char const*)content.data }); @@ -146,7 +155,7 @@ void ue_parse_testing() #define path_SceneComponent \ R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\Components\SceneComponent.h)" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_SceneComponent ); CodeBody parsed_scene_component = parse_global_body( StrC { content.size, (char const*)content.data }); @@ -180,7 +189,7 @@ void ue_parse_testing() #define path_AttributeSet \ R"(C:\projects\Unreal\Surgo\UE\Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public\AttributeSet.h)" -#if 0 +#if 1 content = file_read_contents( GlobalAllocator, true, path_AttributeSet ); CodeBody parsed_attribute_set = parse_global_body( StrC { content.size, (char const*)content.data }); diff --git a/Project/Source/GasaGen/gen.builder.cpp b/Project/Source/GasaGen/gen.builder.cpp index 441e349..64d4751 100644 --- a/Project/Source/GasaGen/gen.builder.cpp +++ b/Project/Source/GasaGen/gen.builder.cpp @@ -14,7 +14,6 @@ Builder Builder::open( char const* path ) log_failure( "gen::File::open - Could not open file: %s", path ); return result; } - result.Buffer = String::make_reserve( GlobalAllocator, Builder_StrBufferReserve ); // log_fmt("$Builder - Opened file: %s\n", result.File.filename ); @@ -37,7 +36,7 @@ void Builder::print( Code code ) void Builder::print_fmt( char const* fmt, ... ) { sw res; - char buf[ GEN_PRINTF_MAXLEN ] = { 0 }; + char buf[GEN_PRINTF_MAXLEN] = { 0 }; va_list va; va_start( va, fmt ); diff --git a/Project/Source/GasaGen/gen.cpp b/Project/Source/GasaGen/gen.cpp index cca08df..3d8187d 100644 --- a/Project/Source/GasaGen/gen.cpp +++ b/Project/Source/GasaGen/gen.cpp @@ -35,11 +35,11 @@ GEN_NS_BEGIN // TODO : Convert global allocation strategy to use a slab allocation strategy. global AllocatorInfo GlobalAllocator; -global Array< Arena > Global_AllocatorBuckets; +global Array Global_AllocatorBuckets; // TODO(Ed) : Make the code pool a dynamic arena -global Array< Pool > CodePools = { nullptr }; -global Array< Arena > StringArenas = { nullptr }; +global Array CodePools = { nullptr }; +global Array StringArenas = { nullptr }; global StringTable StringCache; @@ -110,7 +110,7 @@ global CodeType t_wchar_t; global CodeType t_class; global CodeType t_typename; -global Array< StringCached > PreprocessorDefines; +global Array PreprocessorDefines; #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS global CodeType t_b32; @@ -483,7 +483,7 @@ char const* AST::debug_str() s32 left = NumEntries; while ( left-- ) { - StrC spec = ESpecifier::to_str( ArrSpecs[ idx ] ); + StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); result.append_fmt( "%.*s, ", spec.Len, spec.Ptr ); idx++; } @@ -623,169 +623,169 @@ void AST::to_string( String& result ) break; case Class : - cast< CodeClass >().to_string_def( result ); + cast().to_string_def( result ); break; case Class_Fwd : - cast< CodeClass >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Constructor : - cast< CodeConstructor >().to_string_def( result ); + cast().to_string_def( result ); break; case Constructor_Fwd : - cast< CodeConstructor >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Destructor : - cast< CodeDestructor >().to_string_def( result ); + cast().to_string_def( result ); break; case Destructor_Fwd : - cast< CodeDestructor >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Enum : - cast< CodeEnum >().to_string_def( result ); + cast().to_string_def( result ); break; case Enum_Fwd : - cast< CodeEnum >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Enum_Class : - cast< CodeEnum >().to_string_class_def( result ); + cast().to_string_class_def( result ); break; case Enum_Class_Fwd : - cast< CodeEnum >().to_string_class_fwd( result ); + cast().to_string_class_fwd( result ); break; case Export_Body : - cast< CodeBody >().to_string_export( result ); + cast().to_string_export( result ); break; case Extern_Linkage : - cast< CodeExtern >().to_string( result ); + cast().to_string( result ); break; case Friend : - cast< CodeFriend >().to_string( result ); + cast().to_string( result ); break; case Function : - cast< CodeFn >().to_string_def( result ); + cast().to_string_def( result ); break; case Function_Fwd : - cast< CodeFn >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Module : - cast< CodeModule >().to_string( result ); + cast().to_string( result ); break; case Namespace : - cast< CodeNS >().to_string( result ); + cast().to_string( result ); break; case Operator : case Operator_Member : - cast< CodeOperator >().to_string_def( result ); + cast().to_string_def( result ); break; case Operator_Fwd : case Operator_Member_Fwd : - cast< CodeOperator >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Operator_Cast : - cast< CodeOpCast >().to_string_def( result ); + cast().to_string_def( result ); break; case Operator_Cast_Fwd : - cast< CodeOpCast >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Parameters : - cast< CodeParam >().to_string( result ); + cast().to_string( result ); break; case Preprocess_Define : - cast< CodeDefine >().to_string( result ); + cast().to_string( result ); break; case Preprocess_If : - cast< CodePreprocessCond >().to_string_if( result ); + cast().to_string_if( result ); break; case Preprocess_IfDef : - cast< CodePreprocessCond >().to_string_ifdef( result ); + cast().to_string_ifdef( result ); break; case Preprocess_IfNotDef : - cast< CodePreprocessCond >().to_string_ifndef( result ); + cast().to_string_ifndef( result ); break; case Preprocess_Include : - cast< CodeInclude >().to_string( result ); + cast().to_string( result ); break; case Preprocess_ElIf : - cast< CodePreprocessCond >().to_string_elif( result ); + cast().to_string_elif( result ); break; case Preprocess_Else : - cast< CodePreprocessCond >().to_string_else( result ); + cast().to_string_else( result ); break; case Preprocess_EndIf : - cast< CodePreprocessCond >().to_string_endif( result ); + cast().to_string_endif( result ); break; case Preprocess_Pragma : - cast< CodePragma >().to_string( result ); + cast().to_string( result ); break; case Specifiers : - cast< CodeSpecifiers >().to_string( result ); + cast().to_string( result ); break; case Struct : - cast< CodeStruct >().to_string_def( result ); + cast().to_string_def( result ); break; case Struct_Fwd : - cast< CodeStruct >().to_string_fwd( result ); + cast().to_string_fwd( result ); break; case Template : - cast< CodeTemplate >().to_string( result ); + cast().to_string( result ); break; case Typedef : - cast< CodeTypedef >().to_string( result ); + cast().to_string( result ); break; case Typename : - cast< CodeType >().to_string( result ); + cast().to_string( result ); break; case Union : - cast< CodeUnion >().to_string( result ); + cast().to_string( result ); break; case Using : - cast< CodeUsing >().to_string( result ); + cast().to_string( result ); break; case Using_Namespace : - cast< CodeUsing >().to_string_ns( result ); + cast().to_string_ns( result ); break; case Variable : - cast< CodeVar >().to_string( result ); + cast().to_string( result ); break; case Enum_Body : @@ -796,7 +796,7 @@ void AST::to_string( String& result ) case Namespace_Body : case Struct_Body : case Union_Body : - cast< CodeBody >().to_string( result ); + cast().to_string( result ); break; } } @@ -1243,7 +1243,7 @@ bool AST::is_equal( AST* other ) check_member_str( Name ); for ( s32 idx = 0; idx < NumEntries; ++idx ) { - check_member_val( ArrSpecs[ idx ] ); + check_member_val( ArrSpecs[idx] ); } return true; } @@ -1382,7 +1382,7 @@ bool AST::validate_body() #define CheckEntries( Unallowed_Types ) \ do \ { \ - for ( Code entry : cast< CodeBody >() ) \ + for ( Code entry : cast() ) \ { \ switch ( entry->Type ) \ { \ @@ -1398,7 +1398,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES ); break; case Enum_Body : - for ( Code entry : cast< CodeBody >() ) + for ( Code entry : cast() ) { if ( entry->Type != Untyped ) { @@ -1417,7 +1417,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES ); break; case Global_Body : - for ( Code entry : cast< CodeBody >() ) + for ( Code entry : cast() ) { switch ( entry->Type ) { @@ -1450,7 +1450,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_STRUCT_UNALLOWED_TYPES ); break; case Union_Body : - for ( Code entry : Body->cast< CodeBody >() ) + for ( Code entry : Body->cast() ) { if ( entry->Type != Untyped ) { @@ -1564,10 +1564,12 @@ String CodeConstructor::to_string() void CodeConstructor::to_string_def( String& result ) { AST* ClassStructParent = ast->Parent->Parent; - if (ClassStructParent) { + if ( ClassStructParent ) + { result.append( ClassStructParent->Name ); } - else { + else + { result.append( ast->Name ); } @@ -1588,19 +1590,21 @@ void CodeConstructor::to_string_def( String& result ) void CodeConstructor::to_string_fwd( String& result ) { AST* ClassStructParent = ast->Parent->Parent; - if (ClassStructParent) { + if ( ClassStructParent ) + { result.append( ClassStructParent->Name ); } - else { + else + { result.append( ast->Name ); } if ( ast->Params ) result.append_fmt( "( %S )", ast->Params.to_string() ); else - result.append_fmt("()"); + result.append_fmt( "()" ); - if (ast->Body) + if ( ast->Body ) result.append_fmt( " = %S", ast->Body.to_string() ); if ( ast->InlineCmt ) @@ -1643,14 +1647,14 @@ void CodeClass::to_string_def( String& result ) result.append_fmt( "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() ); - CodeType interface = ast->ParentType->Next->cast< CodeType >(); + CodeType interface = ast->ParentType->Next->cast(); if ( interface ) result.append( "\n" ); while ( interface ) { result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; + interface = interface->Next ? interface->Next->cast() : Code { nullptr }; } } else if ( ast->Name ) @@ -1746,7 +1750,7 @@ void CodeDestructor::to_string_fwd( String& result ) if ( ast->Specs.has( ESpecifier::Pure ) ) result.append( " = 0;" ); - else if (ast->Body) + else if ( ast->Body ) result.append_fmt( " = %S;", ast->Body.to_string() ); } else @@ -1911,7 +1915,7 @@ void CodeFriend::to_string( String& result ) { result.append_fmt( "friend %S", ast->Declaration->to_string() ); - if ( ast->Declaration->Type != ECode::Function && result[ result.length() - 1 ] != ';' ) + if ( ast->Declaration->Type != ECode::Function && result[result.length() - 1] != ';' ) { result.append( ";" ); } @@ -2000,7 +2004,7 @@ void CodeFn::to_string_fwd( String& result ) { for ( SpecifierT spec : ast->Specs ) { - if ( ! ESpecifier::is_trailing( spec ) ) + 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 ); @@ -2029,7 +2033,7 @@ void CodeFn::to_string_fwd( String& result ) { for ( SpecifierT spec : ast->Specs ) { - if ( ESpecifier::is_trailing( spec ) && ! spec != ESpecifier::Pure ) + if ( ESpecifier::is_trailing( spec ) ) { StrC spec_str = ESpecifier::to_str( spec ); result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); @@ -2037,9 +2041,9 @@ void CodeFn::to_string_fwd( String& result ) } } - if ( ast->Specs.has( ESpecifier::Pure ) >= 0 ) + if ( ast->Specs && ast->Specs.has( ESpecifier::Pure ) >= 0 ) result.append( " = 0;" ); - else if (ast->Body) + else if ( ast->Body ) result.append_fmt( " = %S;", ast->Body.to_string() ); if ( ast->InlineCmt ) @@ -2300,7 +2304,6 @@ void CodeParam::to_string( String& result ) result.append_fmt( " %S", ast->Name ); else result.append_fmt( " %S %S", ast->ValueType.to_string(), ast->Name ); - } else if ( ast->ValueType ) result.append_fmt( " %S", ast->ValueType.to_string() ); @@ -2400,7 +2403,7 @@ void CodeSpecifiers::to_string( String& result ) s32 left = ast->NumEntries; while ( left-- ) { - StrC spec = ESpecifier::to_str( ast->ArrSpecs[ idx ] ); + StrC spec = ESpecifier::to_str( ast->ArrSpecs[idx] ); result.append_fmt( "%.*s ", spec.Len, spec.Ptr ); idx++; } @@ -2440,14 +2443,14 @@ void CodeStruct::to_string_def( String& result ) result.append_fmt( "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() ); - CodeType interface = ast->ParentType->Next->cast< CodeType >(); + CodeType interface = ast->ParentType->Next->cast(); if ( interface ) result.append( "\n" ); while ( interface ) { result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; + interface = interface->Next ? interface->Next->cast() : Code { nullptr }; } } else if ( ast->Name ) @@ -2884,7 +2887,7 @@ internal void define_constants() Code::Invalid = make_code(); Code::Invalid.set_global(); - t_empty = ( CodeType )make_code(); + t_empty = (CodeType)make_code(); t_empty->Type = ECode::Typename; t_empty->Name = get_cached_string( txt( "" ) ); t_empty.set_global(); @@ -2926,23 +2929,23 @@ internal void define_constants() fmt_newline->Type = ECode::NewLine; fmt_newline.set_global(); - pragma_once = ( CodePragma )make_code(); + pragma_once = (CodePragma)make_code(); pragma_once->Type = ECode::Preprocess_Pragma; pragma_once->Name = get_cached_string( txt( "once" ) ); pragma_once->Content = pragma_once->Name; pragma_once.set_global(); - param_varadic = ( CodeType )make_code(); + param_varadic = (CodeType)make_code(); param_varadic->Type = ECode::Parameters; param_varadic->Name = get_cached_string( txt( "..." ) ); param_varadic->ValueType = t_empty; param_varadic.set_global(); - preprocess_else = ( CodePreprocessCond )make_code(); + preprocess_else = (CodePreprocessCond)make_code(); preprocess_else->Type = ECode::Preprocess_Else; preprocess_else.set_global(); - preprocess_endif = ( CodePreprocessCond )make_code(); + preprocess_endif = (CodePreprocessCond)make_code(); preprocess_endif->Type = ECode::Preprocess_EndIf; preprocess_endif.set_global(); @@ -3037,7 +3040,7 @@ void init() { GlobalAllocator = AllocatorInfo { &Global_Allocator_Proc, nullptr }; - Global_AllocatorBuckets = Array< Arena >::init_reserve( heap(), 128 ); + Global_AllocatorBuckets = Array::init_reserve( heap(), 128 ); if ( Global_AllocatorBuckets == nullptr ) GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets" ); @@ -3052,12 +3055,12 @@ void init() // Setup the arrays { - CodePools = Array< Pool >::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); + CodePools = Array::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); if ( CodePools == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the CodePools array" ); - StringArenas = Array< Arena >::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); + StringArenas = Array::init_reserve( Allocator_DataArrays, InitSize_DataArrays ); if ( StringArenas == nullptr ) GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" ); @@ -3091,7 +3094,7 @@ void init() } // Preprocessor Defines - PreprocessorDefines = Array< StringCached >::init_reserve( GlobalAllocator, kilobytes( 1 ) ); + PreprocessorDefines = Array::init_reserve( GlobalAllocator, kilobytes( 1 ) ); define_constants(); parser::init(); @@ -3103,7 +3106,7 @@ void deinit() uw left = CodePools.num(); do { - Pool* code_pool = &CodePools[ index ]; + Pool* code_pool = &CodePools[index]; code_pool->free(); index++; } while ( left--, left ); @@ -3112,7 +3115,7 @@ void deinit() left = StringArenas.num(); do { - Arena* string_arena = &StringArenas[ index ]; + Arena* string_arena = &StringArenas[index]; string_arena->free(); index++; } while ( left--, left ); @@ -3130,7 +3133,7 @@ void deinit() left = Global_AllocatorBuckets.num(); do { - Arena* bucket = &Global_AllocatorBuckets[ index ]; + Arena* bucket = &Global_AllocatorBuckets[index]; bucket->free(); index++; } while ( left--, left ); @@ -3145,7 +3148,7 @@ void reset() s32 left = CodePools.num(); do { - Pool* code_pool = &CodePools[ index ]; + Pool* code_pool = &CodePools[index]; code_pool->clear(); index++; } while ( left--, left ); @@ -3154,7 +3157,7 @@ void reset() left = StringArenas.num(); do { - Arena* string_arena = &StringArenas[ index ]; + Arena* string_arena = &StringArenas[index]; string_arena->TotalUsed = 0; ; index++; @@ -3454,14 +3457,17 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy } } break; - case BNot: + + case BNot : { // Some compilers let you do this... - // if ( ! ret_type.is_equal( t_bool) ) - // { - // log_failure( "gen::def_operator: return type is not a boolean - %s", params_code.debug_str() ); - // return OpValidateResult::Fail; - // } +#if 0 + if ( ! ret_type.is_equal( t_bool) ) + { + log_failure( "gen::def_operator: return type is not a boolean - %s", params_code.debug_str() ); + return OpValidateResult::Fail; + } +#endif if ( ! params_code ) is_member_symbol = true; @@ -3621,8 +3627,8 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy check_params(); break; - case New: - case Delete: + case New : + case Delete : // This library doesn't support validating new and delete yet. break; #undef specs @@ -3703,7 +3709,7 @@ CodeAttributes def_attributes( StrC content ) result->Name = get_cached_string( content ); result->Content = result->Name; - return ( CodeAttributes )result; + return (CodeAttributes)result; } CodeComment def_comment( StrC content ) @@ -3714,7 +3720,7 @@ CodeComment def_comment( StrC content ) return CodeInvalid; } - static char line[ MaxCommentLineLength ]; + static char line[MaxCommentLineLength]; String cmt_formatted = String::make_reserve( GlobalAllocator, kilobytes( 1 ) ); char const* end = content.Ptr + content.Len; @@ -3724,7 +3730,7 @@ CodeComment def_comment( StrC content ) { char const* next = scanner; s32 length = 0; - while ( next != end && scanner[ length ] != '\n' ) + while ( next != end && scanner[length] != '\n' ) { next = scanner + length; length++; @@ -3748,7 +3754,7 @@ CodeComment def_comment( StrC content ) cmt_formatted.free(); - return ( CodeComment )result; + return (CodeComment)result; } CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code body ) @@ -3761,7 +3767,7 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b return CodeInvalid; } - CodeConstructor result = ( CodeConstructor )make_code(); + CodeConstructor result = (CodeConstructor)make_code(); if ( params ) { @@ -3824,7 +3830,7 @@ CodeClass def_class( return CodeInvalid; } - CodeClass result = ( CodeClass )make_code(); + CodeClass result = (CodeClass)make_code(); result->Name = get_cached_string( name ); result->ModuleFlags = mflags; @@ -3841,9 +3847,9 @@ CodeClass def_class( return CodeInvalid; } - result->Type = Class; - result->Body = body; - result->Body->Parent = result; + result->Type = Class; + result->Body = body; + result->Body->Parent = result; // TODO(Ed): Review this? } else { @@ -3863,7 +3869,7 @@ CodeClass def_class( { for ( s32 idx = 0; idx < num_interfaces; idx++ ) { - result.add_interface( interfaces[ idx ] ); + result.add_interface( interfaces[idx] ); } } @@ -3876,18 +3882,21 @@ CodeDefine def_define( StrC name, StrC content ) name_check( def_define, name ); - // if ( content.Len <= 0 || content.Ptr == nullptr ) - // { - // log_failure( "gen::def_define: Invalid value provided" ); - // return CodeInvalid; - // } + // Defines can be empty definitions +#if 0 + if ( content.Len <= 0 || content.Ptr == nullptr ) + { + log_failure( "gen::def_define: Invalid value provided" ); + return CodeInvalid; + } +#endif - CodeDefine result = ( CodeDefine )make_code(); + CodeDefine result = (CodeDefine)make_code(); result->Type = Preprocess_Define; result->Name = get_cached_string( name ); if ( content.Len <= 0 || content.Ptr == nullptr ) { - result->Content = get_cached_string( txt("") ); + result->Content = get_cached_string( txt( "" ) ); } else result->Content = get_cached_string( content ); @@ -3905,7 +3914,7 @@ CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers ) return CodeInvalid; } - CodeDestructor result = ( CodeDestructor )make_code(); + CodeDestructor result = (CodeDestructor)make_code(); if ( specifiers ) result->Specs = specifiers; @@ -3952,7 +3961,7 @@ CodeEnum def_enum( StrC name, Code body, CodeType type, EnumT specifier, CodeAtt return CodeInvalid; } - CodeEnum result = ( CodeEnum )make_code(); + CodeEnum result = (CodeEnum)make_code(); result->Name = get_cached_string( name ); result->ModuleFlags = mflags; @@ -4007,7 +4016,7 @@ CodeExec def_execution( StrC content ) result->Name = get_cached_string( content ); result->Content = result->Name; - return ( CodeExec )result; + return (CodeExec)result; } CodeExtern def_extern_link( StrC name, Code body ) @@ -4023,12 +4032,12 @@ CodeExtern def_extern_link( StrC name, Code body ) return CodeInvalid; } - CodeExtern result = ( CodeExtern )make_code(); + CodeExtern result = (CodeExtern)make_code(); result->Type = Extern_Linkage; result->Name = get_cached_string( name ); result->Body = body; - return ( CodeExtern )result; + return (CodeExtern)result; } CodeFriend def_friend( Code declaration ) @@ -4054,7 +4063,7 @@ CodeFriend def_friend( Code declaration ) return CodeInvalid; } - CodeFriend result = ( CodeFriend )make_code(); + CodeFriend result = (CodeFriend)make_code(); result->Type = Friend; result->Declaration = declaration; @@ -4092,7 +4101,7 @@ CodeFn def_function( StrC name, CodeParam params, CodeType ret_type, Code body, return CodeInvalid; } - CodeFn result = ( CodeFn )make_code(); + CodeFn result = (CodeFn)make_code(); result->Name = get_cached_string( name ); result->ModuleFlags = mflags; @@ -4156,7 +4165,7 @@ CodeInclude def_include( StrC path, bool foreign ) result->Name = get_cached_string( content ); result->Content = result->Name; - return ( CodeInclude )result; + return (CodeInclude)result; } CodeModule def_module( StrC name, ModuleFlag mflags ) @@ -4169,7 +4178,7 @@ CodeModule def_module( StrC name, ModuleFlag mflags ) result->Content = result->Name; result->ModuleFlags = mflags; - return ( CodeModule )result; + return (CodeModule)result; } CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags ) @@ -4185,7 +4194,7 @@ CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags ) return CodeInvalid; } - CodeNS result = ( CodeNS )make_code(); + CodeNS result = (CodeNS)make_code(); result->Type = Namespace; result->Name = get_cached_string( name ); result->ModuleFlags = mflags; @@ -4233,7 +4242,7 @@ CodeOperator def_operator( name = str_fmt_buf( "%.*soperator %.*s", nspace.Len, nspace.Ptr, op_str.Len, op_str.Ptr ); else name = str_fmt_buf( "operator %.*s", op_str.Len, op_str.Ptr ); - CodeOperator result = ( CodeOperator )make_code(); + CodeOperator result = (CodeOperator)make_code(); result->Name = get_cached_string( { str_len( name ), name } ); result->ModuleFlags = mflags; result->Op = op; @@ -4288,7 +4297,7 @@ CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spe return CodeInvalid; } - CodeOpCast result = ( CodeOpCast )make_code(); + CodeOpCast result = (CodeOpCast)make_code(); if ( body ) { @@ -4335,7 +4344,7 @@ CodeParam def_param( CodeType type, StrC name, Code value ) return CodeInvalid; } - CodeParam result = ( CodeParam )make_code(); + CodeParam result = (CodeParam)make_code(); result->Type = Parameters; result->Name = get_cached_string( name ); @@ -4359,7 +4368,7 @@ CodePragma def_pragma( StrC directive ) return CodeInvalid; } - CodePragma result = ( CodePragma )make_code(); + CodePragma result = (CodePragma)make_code(); result->Type = Preprocess_Pragma; result->Content = get_cached_string( directive ); @@ -4376,7 +4385,7 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr ) return CodeInvalid; } - CodePreprocessCond result = ( CodePreprocessCond )make_code(); + CodePreprocessCond result = (CodePreprocessCond)make_code(); result->Content = get_cached_string( expr ); switch ( type ) @@ -4400,7 +4409,7 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr ) CodeSpecifiers def_specifier( SpecifierT spec ) { - CodeSpecifiers result = ( CodeSpecifiers )make_code(); + CodeSpecifiers result = (CodeSpecifiers)make_code(); result->Type = ECode::Specifiers; result.append( spec ); @@ -4438,7 +4447,7 @@ CodeStruct def_struct( return CodeInvalid; } - CodeStruct result = ( CodeStruct )make_code(); + CodeStruct result = (CodeStruct)make_code(); result->ModuleFlags = mflags; if ( name ) @@ -4467,7 +4476,7 @@ CodeStruct def_struct( { for ( s32 idx = 0; idx < num_interfaces; idx++ ) { - result.add_interface( interfaces[ idx ] ); + result.add_interface( interfaces[idx] ); } } @@ -4497,7 +4506,7 @@ CodeTemplate def_template( CodeParam params, Code declaration, ModuleFlag mflags log_failure( "gen::def_template: declaration is not of class, function, struct, variable, or using type - %s", declaration.debug_str() ); } - CodeTemplate result = ( CodeTemplate )make_code(); + CodeTemplate result = (CodeTemplate)make_code(); result->Type = ECode::Template; result->ModuleFlags = mflags; result->Params = params; @@ -4528,7 +4537,7 @@ CodeType def_type( StrC name, Code arrayexpr, CodeSpecifiers specifiers, CodeAtt return CodeInvalid; } - CodeType result = ( CodeType )make_code(); + CodeType result = (CodeType)make_code(); result->Name = get_cached_string( name ); result->Type = ECode::Typename; @@ -4584,7 +4593,7 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module return CodeInvalid; } - CodeTypedef result = ( CodeTypedef )make_code(); + CodeTypedef result = (CodeTypedef)make_code(); result->Type = ECode::Typedef; result->ModuleFlags = mflags; @@ -4626,7 +4635,7 @@ CodeUnion def_union( StrC name, Code body, CodeAttributes attributes, ModuleFlag return CodeInvalid; } - CodeUnion result = ( CodeUnion )make_code(); + CodeUnion result = (CodeUnion)make_code(); result->ModuleFlags = mflags; result->Type = ECode::Union; @@ -4660,7 +4669,7 @@ CodeUsing def_using( StrC name, CodeType type, CodeAttributes attributes, Module return CodeInvalid; } - CodeUsing result = ( CodeUsing )make_code(); + CodeUsing result = (CodeUsing)make_code(); result->Name = get_cached_string( name ); result->ModuleFlags = mflags; result->Type = ECode::Using; @@ -4682,7 +4691,7 @@ CodeUsing def_using_namespace( StrC name ) result->Content = result->Name; result->Type = ECode::Using_Namespace; - return ( CodeUsing )result; + return (CodeUsing)result; } CodeVar def_variable( CodeType type, StrC name, Code value, CodeSpecifiers specifiers, CodeAttributes attributes, ModuleFlag mflags ) @@ -4714,7 +4723,7 @@ CodeVar def_variable( CodeType type, StrC name, Code value, CodeSpecifiers speci return CodeInvalid; } - CodeVar result = ( CodeVar )make_code(); + CodeVar result = (CodeVar)make_code(); result->Name = get_cached_string( name ); result->Type = ECode::Variable; result->ModuleFlags = mflags; @@ -4764,7 +4773,7 @@ CodeBody def_class_body( s32 num, ... ) { def_body_start( def_class_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Class_Body; va_list va; @@ -4810,7 +4819,7 @@ CodeBody def_class_body( s32 num, Code* codes ) { def_body_code_array_start( def_class_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Function_Body; do @@ -4853,7 +4862,7 @@ CodeBody def_enum_body( s32 num, ... ) { def_body_start( def_enum_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Enum_Body; va_list va; @@ -4879,14 +4888,14 @@ CodeBody def_enum_body( s32 num, ... ) } while ( num--, num > 0 ); va_end( va ); - return ( CodeBody )result; + return (CodeBody)result; } CodeBody def_enum_body( s32 num, Code* codes ) { def_body_code_array_start( def_enum_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Enum_Body; do @@ -4915,7 +4924,7 @@ CodeBody def_export_body( s32 num, ... ) { def_body_start( def_export_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Export_Body; va_list va; @@ -4961,7 +4970,7 @@ CodeBody def_export_body( s32 num, Code* codes ) { def_body_code_array_start( def_export_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Export_Body; do @@ -5004,7 +5013,7 @@ CodeBody def_extern_link_body( s32 num, ... ) { def_body_start( def_extern_linkage_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Extern_Linkage_Body; va_list va; @@ -5050,7 +5059,7 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) { def_body_code_array_start( def_extern_linkage_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Extern_Linkage_Body; do @@ -5094,7 +5103,7 @@ CodeBody def_function_body( s32 num, ... ) { def_body_start( def_function_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Function_Body; va_list va; @@ -5132,7 +5141,7 @@ CodeBody def_function_body( s32 num, Code* codes ) { def_body_code_array_start( def_function_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Function_Body; do @@ -5174,7 +5183,7 @@ CodeBody def_global_body( s32 num, ... ) { def_body_start( def_global_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Global_Body; va_list va; @@ -5197,7 +5206,7 @@ CodeBody def_global_body( s32 num, ... ) switch ( entry->Type ) { case Global_Body : - result.append( entry.cast< CodeBody >() ); + result.append( entry.cast() ); continue; GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES @@ -5224,7 +5233,7 @@ CodeBody def_global_body( s32 num, Code* codes ) { def_body_code_array_start( def_global_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Global_Body; do @@ -5245,7 +5254,7 @@ CodeBody def_global_body( s32 num, Code* codes ) switch ( entry->Type ) { case Global_Body : - result.append( entry.cast< CodeBody >() ); + result.append( entry.cast() ); continue; GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES @@ -5271,7 +5280,7 @@ CodeBody def_namespace_body( s32 num, ... ) { def_body_start( def_namespace_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Namespace_Body; va_list va; @@ -5317,7 +5326,7 @@ CodeBody def_namespace_body( s32 num, Code* codes ) { def_body_code_array_start( def_namespace_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Global_Body; do @@ -5374,7 +5383,7 @@ CodeParam def_params( s32 num, ... ) return CodeInvalid; } - CodeParam result = ( CodeParam )param.duplicate(); + CodeParam result = (CodeParam)param.duplicate(); while ( --num ) { @@ -5411,10 +5420,10 @@ CodeParam def_params( s32 num, CodeParam* codes ) return CodeInvalid; \ } - CodeParam current = ( CodeParam )codes->duplicate(); + CodeParam current = (CodeParam)codes->duplicate(); check_current(); - CodeParam result = ( CodeParam )make_code(); + CodeParam result = (CodeParam)make_code(); result->Name = current->Name; result->Type = current->Type; result->ValueType = current->ValueType; @@ -5443,14 +5452,14 @@ CodeSpecifiers def_specifiers( s32 num, ... ) return CodeInvalid; } - CodeSpecifiers result = ( CodeSpecifiers )make_code(); + CodeSpecifiers result = (CodeSpecifiers)make_code(); result->Type = ECode::Specifiers; va_list va; va_start( va, num ); do { - SpecifierT type = ( SpecifierT )va_arg( va, int ); + SpecifierT type = (SpecifierT)va_arg( va, int ); result.append( type ); } while ( --num, num ); @@ -5473,13 +5482,13 @@ CodeSpecifiers def_specifiers( s32 num, SpecifierT* specs ) return CodeInvalid; } - CodeSpecifiers result = ( CodeSpecifiers )make_code(); + CodeSpecifiers result = (CodeSpecifiers)make_code(); result->Type = ECode::Specifiers; s32 idx = 0; do { - result.append( specs[ idx ] ); + result.append( specs[idx] ); idx++; } while ( --num, num ); @@ -5490,7 +5499,7 @@ CodeBody def_struct_body( s32 num, ... ) { def_body_start( def_struct_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Struct_Body; va_list va; @@ -5536,7 +5545,7 @@ CodeBody def_struct_body( s32 num, Code* codes ) { def_body_code_array_start( def_struct_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Struct_Body; do @@ -5579,7 +5588,7 @@ CodeBody def_union_body( s32 num, ... ) { def_body_start( def_union_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Union_Body; va_list va; @@ -5612,7 +5621,7 @@ CodeBody def_union_body( s32 num, CodeUnion* codes ) { def_body_code_array_start( def_union_body ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Union_Body; do @@ -5634,7 +5643,7 @@ CodeBody def_union_body( s32 num, CodeUnion* codes ) result.append( entry ); } while ( codes++, num--, num > 0 ); - return ( CodeBody )result; + return (CodeBody)result; } #undef name_check @@ -5651,15 +5660,11 @@ namespace parser { namespace ETokType { -#define GEN_DEFINE_ATTRIBUTE_TOKENS \ - Entry( API_Export, "GEN_API_Export_Code" ) \ - Entry( API_Import, "GEN_API_Import_Code" ) \ - Entry( UE_DEPRECATED, "UE_DEPRECATED(" ) \ - Entry( UMG_API, "UMG_API" ) \ - Entry( COREUOBJECT_API, "COREUOBJECT_API" ) \ - Entry( ENGINE_API, "ENGINE_API" ) \ - Entry( GASA_API, "GASA_API" ) \ - Entry( GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) +#define GEN_DEFINE_ATTRIBUTE_TOKENS \ + Entry( Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Attribute_API_Import, "GEN_API_Import_Code" ) \ + Entry( Attribute_UE_DEPRECATED, "UE_DEPRECATED" ) Entry( Attribute_UMG_API, "UMG_API" ) Entry( Attribute_COREUOBJECT_API, "COREUOBJECT_API" ) \ + Entry( Attribute_ENGINE_API, "ENGINE_API" ) Entry( Attribute_GASA_API, "GASA_API" ) \ + Entry( Attribute_GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) enum Type : u32 { @@ -5758,140 +5763,140 @@ namespace parser Type_MS_W64, Varadic_Argument, __Attributes_Start, - API_Export, - API_Import, - UE_DEPRECATED, - UMG_API, - COREUOBJECT_API, - ENGINE_API, - GASA_API, - GAMEPLAYABILITIES_API, + Attribute_API_Export, + Attribute_API_Import, + Attribute_UE_DEPRECATED, + Attribute_UMG_API, + Attribute_COREUOBJECT_API, + Attribute_ENGINE_API, + Attribute_GASA_API, + Attribute_GAMEPLAYABILITIES_API, NumTokens }; StrC to_str( Type type ) { local_persist StrC lookup[] { - { sizeof( "__invalid__" ), "__invalid__" }, - { sizeof( "private" ), "private" }, - { sizeof( "protected" ), "protected" }, - { sizeof( "public" ), "public" }, - { sizeof( "." ), "." }, - { sizeof( "::" ), "::" }, - { sizeof( "&" ), "&" }, - { sizeof( "&&" ), "&&" }, - { sizeof( ":" ), ":" }, - { sizeof( "[[" ), "[[" }, - { sizeof( "]]" ), "]]" }, - { sizeof( "{" ), "{" }, - { sizeof( "}" ), "}" }, - { sizeof( "[" ), "[" }, - { sizeof( "]" ), "]" }, - { sizeof( "(" ), "(" }, - { sizeof( ")" ), ")" }, - { sizeof( "__comment__" ), "__comment__" }, - { sizeof( "__comment_end__" ), "__comment_end__" }, - { sizeof( "__comment_start__" ), "__comment_start__" }, - { sizeof( "__character__" ), "__character__" }, - { sizeof( "," ), "," }, - { sizeof( "class" ), "class" }, - { sizeof( "__attribute__" ), "__attribute__" }, - { sizeof( "__declspec" ), "__declspec" }, - { sizeof( "enum" ), "enum" }, - { sizeof( "extern" ), "extern" }, - { sizeof( "friend" ), "friend" }, - { sizeof( "module" ), "module" }, - { sizeof( "namespace" ), "namespace" }, - { sizeof( "operator" ), "operator" }, - { sizeof( "struct" ), "struct" }, - { sizeof( "template" ), "template" }, - { sizeof( "typedef" ), "typedef" }, - { sizeof( "using" ), "using" }, - { sizeof( "union" ), "union" }, - { sizeof( "__identifier__" ), "__identifier__" }, - { sizeof( "import" ), "import" }, - { sizeof( "export" ), "export" }, - { sizeof( "__new_line__" ), "__new_line__" }, - { sizeof( "__number__" ), "__number__" }, - { sizeof( "__operator__" ), "__operator__" }, - { sizeof( "#" ), "#" }, - { sizeof( "define" ), "define" }, - { sizeof( "if" ), "if" }, - { sizeof( "ifdef" ), "ifdef" }, - { sizeof( "ifndef" ), "ifndef" }, - { sizeof( "elif" ), "elif" }, - { sizeof( "else" ), "else" }, - { sizeof( "endif" ), "endif" }, - { sizeof( "include" ), "include" }, - { sizeof( "pragma" ), "pragma" }, - { sizeof( "__macro_content__" ), "__macro_content__" }, - { sizeof( "__macro__" ), "__macro__" }, - { sizeof( "__unsupported__" ), "__unsupported__" }, - { sizeof( "alignas" ), "alignas" }, - { sizeof( "const" ), "const" }, - { sizeof( "consteval" ), "consteval" }, - { sizeof( "constexpr" ), "constexpr" }, - { sizeof( "constinit" ), "constinit" }, - { sizeof( "explicit" ), "explicit" }, - { sizeof( "extern" ), "extern" }, - { sizeof( "final" ), "final" }, - { sizeof( "forceinline" ), "forceinline" }, - { sizeof( "global" ), "global" }, - { sizeof( "inline" ), "inline" }, - { sizeof( "internal" ), "internal" }, - { sizeof( "local_persist" ), "local_persist" }, - { sizeof( "mutable" ), "mutable" }, - { sizeof( "neverinline" ), "neverinline" }, - { sizeof( "override" ), "override" }, - { sizeof( "static" ), "static" }, - { sizeof( "thread_local" ), "thread_local" }, - { sizeof( "volatile" ), "volatile" }, - { sizeof( "virtual" ), "virtual" }, - { sizeof( "*" ), "*" }, - { sizeof( ";" ), ";" }, - { sizeof( "static_assert" ), "static_assert" }, - { sizeof( "__string__" ), "__string__" }, - { sizeof( "typename" ), "typename" }, - { sizeof( "unsigned" ), "unsigned" }, - { sizeof( "signed" ), "signed" }, - { sizeof( "short" ), "short" }, - { sizeof( "long" ), "long" }, - { sizeof( "bool" ), "bool" }, - { sizeof( "char" ), "char" }, - { sizeof( "int" ), "int" }, - { sizeof( "double" ), "double" }, - { sizeof( "__int8" ), "__int8" }, - { sizeof( "__int16" ), "__int16" }, - { sizeof( "__int32" ), "__int32" }, - { sizeof( "__int64" ), "__int64" }, - { sizeof( "_W64" ), "_W64" }, - { sizeof( "..." ), "..." }, - { sizeof( "__attrib_start__" ), "__attrib_start__" }, - { sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" }, - { sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" }, - { sizeof( "UE_DEPRECATED" ), "UE_DEPRECATED" }, - { sizeof( "UMG_API" ), "UMG_API" }, - { sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" }, - { sizeof( "ENGINE_API" ), "ENGINE_API" }, - { sizeof( "GASA_API" ), "GASA_API" }, + { sizeof( "__invalid__" ), "__invalid__" }, + { sizeof( "private" ), "private" }, + { sizeof( "protected" ), "protected" }, + { sizeof( "public" ), "public" }, + { sizeof( "." ), "." }, + { sizeof( "::" ), "::" }, + { sizeof( "&" ), "&" }, + { sizeof( "&&" ), "&&" }, + { sizeof( ":" ), ":" }, + { sizeof( "[[" ), "[[" }, + { sizeof( "]]" ), "]]" }, + { sizeof( "{" ), "{" }, + { sizeof( "}" ), "}" }, + { sizeof( "[" ), "[" }, + { sizeof( "]" ), "]" }, + { sizeof( "(" ), "(" }, + { sizeof( ")" ), ")" }, + { sizeof( "__comment__" ), "__comment__" }, + { sizeof( "__comment_end__" ), "__comment_end__" }, + { sizeof( "__comment_start__" ), "__comment_start__" }, + { sizeof( "__character__" ), "__character__" }, + { sizeof( "," ), "," }, + { sizeof( "class" ), "class" }, + { sizeof( "__attribute__" ), "__attribute__" }, + { sizeof( "__declspec" ), "__declspec" }, + { sizeof( "enum" ), "enum" }, + { sizeof( "extern" ), "extern" }, + { sizeof( "friend" ), "friend" }, + { sizeof( "module" ), "module" }, + { sizeof( "namespace" ), "namespace" }, + { sizeof( "operator" ), "operator" }, + { sizeof( "struct" ), "struct" }, + { sizeof( "template" ), "template" }, + { sizeof( "typedef" ), "typedef" }, + { sizeof( "using" ), "using" }, + { sizeof( "union" ), "union" }, + { sizeof( "__identifier__" ), "__identifier__" }, + { sizeof( "import" ), "import" }, + { sizeof( "export" ), "export" }, + { sizeof( "__new_line__" ), "__new_line__" }, + { sizeof( "__number__" ), "__number__" }, + { sizeof( "__operator__" ), "__operator__" }, + { sizeof( "#" ), "#" }, + { sizeof( "define" ), "define" }, + { sizeof( "if" ), "if" }, + { sizeof( "ifdef" ), "ifdef" }, + { sizeof( "ifndef" ), "ifndef" }, + { sizeof( "elif" ), "elif" }, + { sizeof( "else" ), "else" }, + { sizeof( "endif" ), "endif" }, + { sizeof( "include" ), "include" }, + { sizeof( "pragma" ), "pragma" }, + { sizeof( "__macro_content__" ), "__macro_content__" }, + { sizeof( "__macro__" ), "__macro__" }, + { sizeof( "__unsupported__" ), "__unsupported__" }, + { sizeof( "alignas" ), "alignas" }, + { sizeof( "const" ), "const" }, + { sizeof( "consteval" ), "consteval" }, + { sizeof( "constexpr" ), "constexpr" }, + { sizeof( "constinit" ), "constinit" }, + { sizeof( "explicit" ), "explicit" }, + { sizeof( "extern" ), "extern" }, + { sizeof( "final" ), "final" }, + { sizeof( "forceinline" ), "forceinline" }, + { sizeof( "global" ), "global" }, + { sizeof( "inline" ), "inline" }, + { sizeof( "internal" ), "internal" }, + { sizeof( "local_persist" ), "local_persist" }, + { sizeof( "mutable" ), "mutable" }, + { sizeof( "neverinline" ), "neverinline" }, + { sizeof( "override" ), "override" }, + { sizeof( "static" ), "static" }, + { sizeof( "thread_local" ), "thread_local" }, + { sizeof( "volatile" ), "volatile" }, + { sizeof( "virtual" ), "virtual" }, + { sizeof( "*" ), "*" }, + { sizeof( ";" ), ";" }, + { sizeof( "static_assert" ), "static_assert" }, + { sizeof( "__string__" ), "__string__" }, + { sizeof( "typename" ), "typename" }, + { sizeof( "unsigned" ), "unsigned" }, + { sizeof( "signed" ), "signed" }, + { sizeof( "short" ), "short" }, + { sizeof( "long" ), "long" }, + { sizeof( "bool" ), "bool" }, + { sizeof( "char" ), "char" }, + { sizeof( "int" ), "int" }, + { sizeof( "double" ), "double" }, + { sizeof( "__int8" ), "__int8" }, + { sizeof( "__int16" ), "__int16" }, + { sizeof( "__int32" ), "__int32" }, + { sizeof( "__int64" ), "__int64" }, + { sizeof( "_W64" ), "_W64" }, + { sizeof( "..." ), "..." }, + { sizeof( "__attrib_start__" ), "__attrib_start__" }, + { sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" }, + { sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" }, + { sizeof( "UE_DEPRECATED" ), "UE_DEPRECATED" }, + { sizeof( "UMG_API" ), "UMG_API" }, + { sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" }, + { sizeof( "ENGINE_API" ), "ENGINE_API" }, + { sizeof( "GASA_API" ), "GASA_API" }, { sizeof( "GAMEPLAYABILITIES_API" ), "GAMEPLAYABILITIES_API" }, }; - return lookup[ type ]; + return lookup[type]; } Type to_type( StrC str ) { - local_persist u32 keymap[ NumTokens ]; + local_persist u32 keymap[NumTokens]; do_once_start for ( u32 index = 0; index < NumTokens; index++ ) { - StrC enum_str = to_str( ( Type )index ); - keymap[ index ] = crc32( enum_str.Ptr, enum_str.Len - 1 ); + StrC enum_str = to_str( (Type)index ); + keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); } do_once_end u32 hash = crc32( str.Ptr, str.Len ); for ( u32 index = 0; index < NumTokens; index++ ) { - if ( keymap[ index ] == hash ) - return ( Type )index; + if ( keymap[index] == hash ) + return (Type)index; } return Invalid; } @@ -6002,8 +6007,8 @@ namespace parser struct TokArray { - Array< Token > Arr; - s32 Idx; + Array Arr; + s32 Idx; bool __eat( TokType type ); @@ -6011,11 +6016,11 @@ namespace parser { if ( skip_formatting ) { - while ( Arr[ Idx ].Type == TokType::NewLine || Arr[ Idx ].Type == TokType::Comment ) + while ( Arr[Idx].Type == TokType::NewLine || Arr[Idx].Type == TokType::Comment ) Idx++; } - return Arr[ Idx ]; + return Arr[Idx]; } Token& previous( bool skip_formatting = false ) @@ -6024,13 +6029,13 @@ namespace parser if ( skip_formatting ) { - while ( Arr[ idx ].Type == TokType::NewLine ) + while ( Arr[idx].Type == TokType::NewLine ) idx--; - return Arr[ idx ]; + return Arr[idx]; } - return Arr[ idx - 1 ]; + return Arr[idx - 1]; } Token& next( bool skip_formatting = false ) @@ -6039,24 +6044,24 @@ namespace parser if ( skip_formatting ) { - while ( Arr[ idx ].Type == TokType::NewLine ) + while ( Arr[idx].Type == TokType::NewLine ) idx++; - return Arr[ idx + 1 ]; + return Arr[idx + 1]; } - return Arr[ idx + 1 ]; + return Arr[idx + 1]; } Token& operator[]( s32 idx ) { - return Arr[ idx ]; + return Arr[idx]; } }; global Arena_128KB defines_map_arena; - global HashTable< StrC > defines; - global Array< Token > Tokens; + global HashTable defines; + global Array Tokens; #define current ( *scanner ) @@ -6105,8 +6110,7 @@ namespace parser Lex_ReturnNull, }; - forceinline s32 - lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable< StrC >& defines, Token& token ) + forceinline s32 lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { char const* hash = scanner; Tokens.append( { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); @@ -6340,7 +6344,7 @@ namespace parser return Lex_Continue; // Skip found token, its all handled here. } - forceinline void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable< StrC >& defines, Token& token ) + forceinline void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { if ( token.Type != TokType::Invalid ) { @@ -6350,7 +6354,7 @@ namespace parser TokType type = ETokType::to_type( token ); - if (type <= TokType::Access_Public && type >= TokType::Access_Private ) + if ( type <= TokType::Access_Public && type >= TokType::Access_Private ) { token.Flags |= TF_AccessSpecifier; } @@ -6425,7 +6429,7 @@ namespace parser token.Length++; } - if ( current == '\r' && scanner[ 1 ] == '\n' ) + if ( current == '\r' && scanner[1] == '\n' ) { move_forward(); } @@ -6472,7 +6476,7 @@ namespace parser scanner++; length++; } - if ( scanner[ 0 ] == '(' ) + if ( scanner[0] == '(' ) { length++; } @@ -6989,7 +6993,7 @@ namespace parser move_forward(); bool star = current == '*'; - bool slash = scanner[ 1 ] == '/'; + bool slash = scanner[1] == '/'; bool at_end = star && slash; while ( left && ! at_end ) { @@ -6997,7 +7001,7 @@ namespace parser token.Length++; star = current == '*'; - slash = scanner[ 1 ] == '/'; + slash = scanner[1] == '/'; at_end = star && slash; } token.Length += 2; @@ -7087,7 +7091,7 @@ namespace parser log_fmt( "\n%d\n", start ); for ( s32 idx = start; idx < Tokens.num(); idx++ ) { - log_fmt( "Token %d Type: %s : %.*s\n", idx, ETokType::to_str( Tokens[ idx ].Type ).Ptr, Tokens[ idx ].Length, Tokens[ idx ].Text ); + log_fmt( "Token %d Type: %s : %.*s\n", idx, ETokType::to_str( Tokens[idx].Type ).Ptr, Tokens[idx].Length, Tokens[idx].Text ); } String context_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 100, left ), scanner ); @@ -7166,7 +7170,7 @@ namespace parser String result = String::make_reserve( GlobalAllocator, kilobytes( 4 ) ); Token scope_start = Scope->Start; - Token last_valid = Tokens.Idx >= Tokens.Arr.num() ? Tokens.Arr[ Tokens.Arr.num() - 1 ] : Tokens.current(); + Token last_valid = Tokens.Idx >= Tokens.Arr.num() ? Tokens.Arr[Tokens.Arr.num() - 1] : Tokens.current(); sptr length = scope_start.Length; char const* current = scope_start.Text + length; @@ -7180,7 +7184,7 @@ namespace parser result.append_fmt( "\tScope : %s\n", line ); line.free(); - sptr dist = ( sptr )last_valid.Text - ( sptr )scope_start.Text + 2; + sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text + 2; sptr length_from_err = dist; String line_from_err = String::make( GlobalAllocator, { length_from_err, last_valid.Text } ); @@ -7219,18 +7223,18 @@ namespace parser return false; } - if ( ( Arr[ Idx ].Type == TokType::NewLine && type != TokType::NewLine ) || ( Arr[ Idx ].Type == TokType::Comment && type != TokType::Comment ) ) + if ( ( Arr[Idx].Type == TokType::NewLine && type != TokType::NewLine ) || ( Arr[Idx].Type == TokType::Comment && type != TokType::Comment ) ) { Idx++; } - if ( Arr[ Idx ].Type != type ) + if ( Arr[Idx].Type != type ) { log_failure( "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s", ETokType::to_str( type ).Ptr, - Arr[ Idx ].Length, - Arr[ Idx ].Text, + Arr[Idx].Length, + Arr[Idx].Text, current().Line, current().Column, Context.to_string() @@ -7249,10 +7253,10 @@ namespace parser internal void init() { - Tokens = Array< Token >::init_reserve( LexArena, ( LexAllocator_Size - sizeof( Array< Token >::Header ) ) / sizeof( Token ) ); + Tokens = Array::init_reserve( LexArena, ( LexAllocator_Size - sizeof( Array::Header ) ) / sizeof( Token ) ); defines_map_arena = Arena_128KB::init(); - defines = HashTable< StrC >::init( defines_map_arena ); + defines = HashTable::init( defines_map_arena ); } internal void deinit() @@ -7370,7 +7374,7 @@ namespace parser sptr last_cut = 0; char const* scanner = raw_text.Ptr; - if ( scanner[ 0 ] == ' ' ) + if ( scanner[0] == ' ' ) { move_fwd(); last_cut = 1; @@ -7382,13 +7386,13 @@ namespace parser while ( tokleft ) { // Skip over the content of string literals - if ( scanner[ 0 ] == '"' ) + if ( scanner[0] == '"' ) { move_fwd(); - while ( tokleft && ( scanner[ 0 ] != '"' || *( scanner - 1 ) == '\\' ) ) + while ( tokleft && ( scanner[0] != '"' || *( scanner - 1 ) == '\\' ) ) { - if ( scanner[ 0 ] == '\\' && tokleft > 1 ) + if ( scanner[0] == '\\' && tokleft > 1 ) { scanner += 2; tokleft -= 2; @@ -7409,11 +7413,11 @@ namespace parser } // Skip over the content of character literals - if ( scanner[ 0 ] == '\'' ) + if ( scanner[0] == '\'' ) { move_fwd(); - while ( tokleft && ( scanner[ 0 ] != '\'' || ( *( scanner - 1 ) == '\\' ) ) ) + while ( tokleft && ( scanner[0] != '\'' || ( *( scanner - 1 ) == '\\' ) ) ) { move_fwd(); } @@ -7428,9 +7432,9 @@ namespace parser } // Block comments - if ( tokleft > 1 && scanner[ 0 ] == '/' && scanner[ 1 ] == '*' ) + if ( tokleft > 1 && scanner[0] == '/' && scanner[1] == '*' ) { - while ( tokleft > 1 && ! ( scanner[ 0 ] == '*' && scanner[ 1 ] == '/' ) ) + while ( tokleft > 1 && ! ( scanner[0] == '*' && scanner[1] == '/' ) ) move_fwd(); scanner += 2; @@ -7442,14 +7446,14 @@ namespace parser } // Line comments - if ( tokleft > 1 && scanner[ 0 ] == '/' && scanner[ 1 ] == '/' ) + if ( tokleft > 1 && scanner[0] == '/' && scanner[1] == '/' ) { must_keep_newline = true; scanner += 2; tokleft -= 2; - while ( tokleft && scanner[ 0 ] != '\n' ) + while ( tokleft && scanner[0] != '\n' ) move_fwd(); if ( tokleft ) @@ -7461,7 +7465,7 @@ namespace parser } // Tabs - if ( scanner[ 0 ] == '\t' ) + if ( scanner[0] == '\t' ) { if ( pos > last_cut ) content.append( cut_ptr, cut_length ); @@ -7474,7 +7478,7 @@ namespace parser continue; } - if ( tokleft > 1 && scanner[ 0 ] == '\r' && scanner[ 1 ] == '\n' ) + if ( tokleft > 1 && scanner[0] == '\r' && scanner[1] == '\n' ) { if ( must_keep_newline || preserve_newlines ) { @@ -7502,7 +7506,7 @@ namespace parser continue; } - if ( scanner[ 0 ] == '\n' ) + if ( scanner[0] == '\n' ) { if ( must_keep_newline || preserve_newlines ) { @@ -7529,16 +7533,16 @@ namespace parser } // Escaped newlines - if ( scanner[ 0 ] == '\\' ) + if ( scanner[0] == '\\' ) { content.append( cut_ptr, cut_length ); s32 amount_to_skip = 1; - if ( tokleft > 1 && scanner[ 1 ] == '\n' ) + if ( tokleft > 1 && scanner[1] == '\n' ) { amount_to_skip = 2; } - else if ( tokleft > 2 && scanner[ 1 ] == '\r' && scanner[ 2 ] == '\n' ) + else if ( tokleft > 2 && scanner[1] == '\r' && scanner[2] == '\n' ) { amount_to_skip = 3; } @@ -7556,13 +7560,13 @@ namespace parser } // Consectuive spaces - if ( tokleft > 1 && char_is_space( scanner[ 0 ] ) && char_is_space( scanner[ 1 ] ) ) + if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[1] ) ) { content.append( cut_ptr, cut_length ); do { move_fwd(); - } while ( tokleft && char_is_space( scanner[ 0 ] ) ); + } while ( tokleft && char_is_space( scanner[0] ) ); last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); @@ -7593,7 +7597,7 @@ namespace parser { push_scope(); - if ( check( TokType::Operator ) && currtok.Text[ 0 ] == '[' && currtok.Text[ 1 ] == ']' ) + if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' ) { Code array_expr = untyped_str( currtok ); eat( TokType::Operator ); @@ -7629,7 +7633,7 @@ namespace parser eat( currtok.Type ); } - untyped_tok.Length = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )untyped_tok.Text; + untyped_tok.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)untyped_tok.Text; Code array_expr = untyped_str( untyped_tok ); // [ @@ -7693,7 +7697,7 @@ namespace parser eat( TokType::Attribute_Close ); // [[ ]] - len = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )start.Text; + len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; } else if ( check( TokType::Decl_GNU_Attribute ) ) { @@ -7712,7 +7716,7 @@ namespace parser eat( TokType::Capture_End ); // __attribute__(( )) - len = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )start.Text; + len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; } else if ( check( TokType::Decl_MSVC_Attribute ) ) { @@ -7729,7 +7733,7 @@ namespace parser eat( TokType::Capture_End ); // __declspec( ) - len = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )start.Text; + len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; } else if ( currtok.is_attribute() ) { @@ -7737,23 +7741,23 @@ namespace parser // // If its a macro based attribute, this could be a functional macro such as Unreal's UE_DEPRECATED(...) - if ( check( TokType::Capture_Start)) + if ( check( TokType::Capture_Start ) ) { eat( TokType::Capture_Start ); s32 level = 0; - while (left && currtok.Type != TokType::Capture_End && level == 0) + while ( left && currtok.Type != TokType::Capture_End && level == 0 ) { - if (currtok.Type == TokType::Capture_Start) - ++ level; - if (currtok.Type == TokType::Capture_End) + if ( currtok.Type == TokType::Capture_Start ) + ++level; + if ( currtok.Type == TokType::Capture_End ) --level; - eat(currtok.Type); + eat( currtok.Type ); } - eat(TokType::Capture_End); + eat( TokType::Capture_End ); } - len = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )start.Text; + len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; // ( ... ) } } @@ -7771,7 +7775,7 @@ namespace parser result->Content = result->Name; // result->Token = - return ( CodeAttributes )result; + return (CodeAttributes)result; } Context.pop(); @@ -7816,8 +7820,8 @@ namespace parser } // - local_persist char interface_arr_mem[ kilobytes( 4 ) ] { 0 }; - Array< CodeType > interfaces = Array< CodeType >::init_reserve( Arena::init_from_memory( interface_arr_mem, kilobytes( 4 ) ), 4 ); + local_persist char interface_arr_mem[kilobytes( 4 )] { 0 }; + Array interfaces = Array::init_reserve( Arena::init_from_memory( interface_arr_mem, kilobytes( 4 ) ), 4 ); // TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them. if ( check( TokType::Assign_Classifer ) ) @@ -7874,7 +7878,7 @@ namespace parser result = def_class( name, body, parent, access, attributes, mflags ); else - result = def_struct( name, body, ( CodeType )parent, access, attributes, mflags ); + result = def_struct( name, body, (CodeType)parent, access, attributes, mflags ); if ( inline_cmt ) result->InlineCmt = inline_cmt; @@ -7886,13 +7890,12 @@ namespace parser internal neverinline CodeBody parse_class_struct_body( TokType which, Token name ) { using namespace ECode; - push_scope(); eat( TokType::BraceCurly_Open ); // { - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); if ( which == TokType::Decl_Class ) result->Type = Class_Body; @@ -7908,17 +7911,17 @@ namespace parser bool expects_function = false; - // Context.Scope->Start = currtok_noskip; + // Context.Scope->Start = currtok_noskip; if ( currtok_noskip.Type == TokType::Preprocess_Hash ) eat( TokType::Preprocess_Hash ); switch ( currtok_noskip.Type ) { - case TokType::Statement_End: + case TokType::Statement_End : { // TODO(Ed): Convert this to a general warning procedure - log_fmt("Dangling end statement found %S\n", currtok_noskip.to_string()); + log_fmt( "Dangling end statement found %S\n", currtok_noskip.to_string() ); eat( TokType::Statement_End ); continue; } @@ -7998,7 +8001,7 @@ namespace parser break; case TokType::Operator : - if ( currtok.Text[ 0 ] != '~' ) + if ( currtok.Text[0] != '~' ) { log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() ); return CodeInvalid; @@ -8072,16 +8075,16 @@ namespace parser case TokType::Spec_Consteval : case TokType::Spec_Constexpr : case TokType::Spec_Constinit : - case TokType::Spec_Explicit: + case TokType::Spec_Explicit : case TokType::Spec_ForceInline : case TokType::Spec_Inline : case TokType::Spec_Mutable : case TokType::Spec_NeverInline : case TokType::Spec_Static : case TokType::Spec_Volatile : - case TokType::Spec_Virtual: + case TokType::Spec_Virtual : { - SpecifierT specs_found[ 16 ] { ESpecifier::NumSpecifiers }; + SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; s32 NumSpecifiers = 0; while ( left && currtok.is_specifier() ) @@ -8094,14 +8097,14 @@ namespace parser { case ESpecifier::Constexpr : case ESpecifier::Constinit : - case ESpecifier::Explicit: + case ESpecifier::Explicit : case ESpecifier::Inline : case ESpecifier::ForceInline : case ESpecifier::Mutable : case ESpecifier::NeverInline : case ESpecifier::Static : case ESpecifier::Volatile : - case ESpecifier::Virtual: + case ESpecifier::Virtual : break; case ESpecifier::Consteval : @@ -8119,10 +8122,10 @@ namespace parser } // Every specifier after would be considered part of the type type signature - if (ignore_spec) + if ( ignore_spec ) break; - specs_found[ NumSpecifiers ] = spec; + specs_found[NumSpecifiers] = spec; NumSpecifiers++; eat( currtok.Type ); } @@ -8143,7 +8146,7 @@ namespace parser String fused = String::make_reserve( GlobalAllocator, attributes->Content.length() + more_attributes->Content.length() ); fused.append_fmt( "%S %S", attributes->Content, more_attributes->Content ); - attributes->Name = get_cached_string(fused); + attributes->Name = get_cached_string( fused ); attributes->Content = attributes->Name; // } @@ -8151,7 +8154,7 @@ namespace parser attributes = more_attributes; } - if ( currtok.Type == TokType::Operator && currtok.Text[ 0 ] == '~' ) + if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' ) { member = parse_destructor( specifiers ); // ~() @@ -8199,7 +8202,7 @@ namespace parser while ( left && currtok.Type != TokType::BraceCurly_Close ) { - untyped_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )untyped_tok.Text; + untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; eat( currtok.Type ); } @@ -8229,7 +8232,7 @@ namespace parser StackNode scope { nullptr, currtok_noskip, NullToken, txt( __func__ ) }; Context.push( &scope ); - CodeComment result = ( CodeComment )make_code(); + CodeComment result = (CodeComment)make_code(); result->Type = ECode::Comment; result->Content = get_cached_string( currtok_noskip ); result->Name = result->Content; @@ -8252,13 +8255,13 @@ namespace parser s32 level = 0; for ( ; idx < tokens.Arr.num(); idx++ ) { - if ( tokens[ idx ].Type == TokType::BraceCurly_Open ) + if ( tokens[idx].Type == TokType::BraceCurly_Open ) level++; - if ( tokens[ idx ].Type == TokType::BraceCurly_Close ) + if ( tokens[idx].Type == TokType::BraceCurly_Close ) level--; - if ( level == 0 && tokens[ idx ].Type == TokType::Statement_End ) + if ( level == 0 && tokens[idx].Type == TokType::Statement_End ) break; } @@ -8271,23 +8274,23 @@ namespace parser return result; } - Token tok = tokens[ idx - 1 ]; - if ( tok.is_specifier() && is_trailing( ESpecifier::to_type(tok)) ) + Token tok = tokens[idx - 1]; + if ( tok.is_specifier() && is_trailing( ESpecifier::to_type( tok ) ) ) { // (...) ...; s32 spec_idx = idx - 1; Token spec = tokens[spec_idx]; - while ( spec.is_specifier() && is_trailing( ESpecifier::to_type(spec)) ) + while ( spec.is_specifier() && is_trailing( ESpecifier::to_type( spec ) ) ) { - -- spec_idx; + --spec_idx; spec = tokens[spec_idx]; } if ( tokens[spec_idx].Type == TokType::Capture_End ) { // Forward declaration with trailing specifiers for a procedure - tok = tokens[spec_idx]; + tok = tokens[spec_idx]; Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } ); // , or Name> ... @@ -8295,13 +8298,13 @@ namespace parser return result; } - log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); + log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str( which ), Context.to_string() ); Context.pop(); return CodeInvalid; } if ( tok.Type == TokType::Identifier ) { - tok = tokens[ idx - 2 ]; + tok = tokens[idx - 2]; bool is_indirection = tok.Type == TokType::Ampersand || tok.Type == TokType::Star; bool ok_to_parse = false; @@ -8312,16 +8315,14 @@ namespace parser ok_to_parse = true; is_inplace = true; } - else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == which ) + else if ( tok.Type == TokType::Identifier && tokens[idx - 3].Type == which ) { // Its a variable with type ID using namespace. // ; ok_to_parse = true; } else if ( tok.Type == TokType::Assign_Classifer - && ( ( tokens[idx - 5].Type == which && tokens[idx - 4].Type == TokType::Decl_Class ) - || ( tokens[idx - 4].Type == which)) - ) + && ( ( tokens[idx - 5].Type == which && tokens[idx - 4].Type == TokType::Decl_Class ) || ( tokens[idx - 4].Type == which ) ) ) { // Its a forward declaration of an enum // : ; @@ -8340,7 +8341,7 @@ namespace parser if ( ! ok_to_parse ) { - log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); + log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str( which ), Context.to_string() ); Context.pop(); return CodeInvalid; } @@ -8352,14 +8353,12 @@ namespace parser } else if ( tok.Type >= TokType::Type_Unsigned && tok.Type <= TokType::Type_MS_W64 ) { - tok = tokens[ idx - 2 ]; + tok = tokens[idx - 2]; if ( tok.Type != TokType::Assign_Classifer - || ( ( tokens[idx - 5].Type != which && tokens[idx - 4].Type != TokType::Decl_Class ) - && ( tokens[idx - 4].Type != which)) - ) + || ( ( tokens[idx - 5].Type != which && tokens[idx - 4].Type != TokType::Decl_Class ) && ( tokens[idx - 4].Type != which ) ) ) { - log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); + log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str( which ), Context.to_string() ); Context.pop(); return CodeInvalid; } @@ -8389,7 +8388,7 @@ namespace parser } else { - log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str(which).Ptr, Context.to_string() ); + log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str( which ).Ptr, Context.to_string() ); Context.pop(); return CodeInvalid; } @@ -8401,7 +8400,7 @@ namespace parser eat( TokType::Preprocess_Define ); // #define - CodeDefine define = ( CodeDefine )make_code(); + CodeDefine define = (CodeDefine)make_code(); define->Type = ECode::Preprocess_Define; if ( ! check( TokType::Identifier ) ) @@ -8441,8 +8440,7 @@ namespace parser return define; } - internal inline - Code parse_assignment_expression() + internal inline Code parse_assignment_expression() { Code expr = { nullptr }; @@ -8459,17 +8457,17 @@ namespace parser } s32 level = 0; - while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) ) + while ( left && currtok.Type != TokType::Statement_End && ( currtok.Type != TokType::Comma || level > 0 ) ) { - if (currtok.Type == TokType::Capture_Start) + if ( currtok.Type == TokType::Capture_Start ) level++; - else if (currtok.Type == TokType::Capture_End) + else if ( currtok.Type == TokType::Capture_End ) level--; eat( currtok.Type ); } - expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1; + expr_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)expr_tok.Text - 1; expr = untyped_str( expr_tok ); // = return expr; @@ -8544,12 +8542,12 @@ namespace parser } // ( ) { } } - else if ( check(TokType::Operator) && currtok.Text[0] == '=' ) + else if ( check( TokType::Operator ) && currtok.Text[0] == '=' ) { - eat(TokType::Operator); + eat( TokType::Operator ); specifiers.append( ESpecifier::Pure ); - eat( TokType::Number); + eat( TokType::Number ); Token stmt_end = currtok; eat( TokType::Statement_End ); // ( ) = 0; @@ -8574,7 +8572,7 @@ namespace parser String name_stripped = String::make( GlobalAllocator, name ); name_stripped.strip_space(); - CodeFn result = ( CodeFn )make_code(); + CodeFn result = (CodeFn)make_code(); result->Name = get_cached_string( name_stripped ); result->ModuleFlags = mflags; @@ -8627,7 +8625,7 @@ namespace parser eat( TokType::BraceCurly_Open ); - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = Function_Body; // TODO : Support actual parsing of function body @@ -8647,7 +8645,7 @@ namespace parser Token previous = prevtok; - s32 len = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )start.Text; + s32 len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; if ( len > 0 ) { @@ -8673,7 +8671,7 @@ namespace parser eat( TokType::BraceCurly_Open ); // { - CodeBody result = ( CodeBody )make_code(); + CodeBody result = (CodeBody)make_code(); result->Type = which; while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) @@ -8684,17 +8682,17 @@ namespace parser bool expects_function = false; - // Context.Scope->Start = currtok_noskip; + // Context.Scope->Start = currtok_noskip; if ( currtok_noskip.Type == TokType::Preprocess_Hash ) eat( TokType::Preprocess_Hash ); switch ( currtok_noskip.Type ) { - case TokType::Statement_End: + case TokType::Statement_End : { // TODO(Ed): Convert this to a general warning procedure - log_fmt("Dangling end statement found %S\n", currtok_noskip.to_string()); + log_fmt( "Dangling end statement found %S\n", currtok_noskip.to_string() ); eat( TokType::Statement_End ); continue; } @@ -8842,7 +8840,7 @@ namespace parser case TokType::Spec_NeverInline : case TokType::Spec_Static : { - SpecifierT specs_found[ 16 ] { ESpecifier::NumSpecifiers }; + SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; s32 NumSpecifiers = 0; while ( left && currtok.is_specifier() ) @@ -8885,7 +8883,7 @@ namespace parser if ( ignore_spec ) break; - specs_found[ NumSpecifiers ] = spec; + specs_found[NumSpecifiers] = spec; NumSpecifiers++; eat( currtok.Type ); } @@ -8917,16 +8915,16 @@ namespace parser } bool found_operator_cast_outside_class_implmentation = false; - s32 idx = Context.Tokens.Idx; + s32 idx = Context.Tokens.Idx; for ( ; idx < Context.Tokens.Arr.num(); idx++ ) { - Token tok = Context.Tokens[ idx ]; + Token tok = Context.Tokens[idx]; if ( tok.Type == TokType::Identifier ) { idx++; - tok = Context.Tokens[ idx ]; + tok = Context.Tokens[idx]; if ( tok.Type == TokType::Access_StaticSymbol ) continue; @@ -8970,28 +8968,27 @@ namespace parser return result; } - internal inline - Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ) + internal inline Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ) { Code result = { nullptr }; /* - To check if a definition is for a constructor we can go straight to the opening parenthesis for its parameters - From There we work backwards to see if we come across two identifiers with the same name between an member access - :: operator, there can be template parameters on the left of the :: so we ignore those. - Whats important is that its back to back. + To check if a definition is for a constructor we can go straight to the opening parenthesis for its parameters + From There we work backwards to see if we come across two identifiers with the same name between an member access + :: operator, there can be template parameters on the left of the :: so we ignore those. + Whats important is that its back to back. - This has multiple possible faults. What we parse using this method may not filter out if something has a "return type" - This is bad since technically you could have a namespace nested into another namespace with the same name. - If this awful pattern is done the only way to distiguish with this coarse parse is to know there is no return type defined. + This has multiple possible faults. What we parse using this method may not filter out if something has a "return type" + This is bad since technically you could have a namespace nested into another namespace with the same name. + If this awful pattern is done the only way to distiguish with this coarse parse is to know there is no return type defined. - TODO(Ed): We could fix this by attempting to parse a type, but we would have to have a way to have it soft fail and rollback. + TODO(Ed): We could fix this by attempting to parse a type, but we would have to have a way to have it soft fail and rollback. */ TokArray tokens = Context.Tokens; - s32 idx = tokens.Idx; - Token nav = tokens[ idx ]; - for ( ; idx < tokens.Arr.num(); idx++, nav = tokens[ idx ] ) + s32 idx = tokens.Idx; + Token nav = tokens[idx]; + for ( ; idx < tokens.Arr.num(); idx++, nav = tokens[idx] ) { if ( nav.Text[0] == '<' ) { @@ -9000,24 +8997,24 @@ namespace parser s32 template_level = 0; for ( ; idx < tokens.Arr.num(); idx++, nav = tokens[idx] ) { - if (nav.Text[ 0 ] == '<') - ++ template_level; + if ( nav.Text[0] == '<' ) + ++template_level; - if (nav.Text[ 0 ] == '>') - -- template_level; - if (nav.Type == TokType::Operator && nav.Text[1] == '>') - -- template_level; + if ( nav.Text[0] == '>' ) + --template_level; + if ( nav.Type == TokType::Operator && nav.Text[1] == '>' ) + --template_level; - if ( nav.Type == ETokType::Capture_Start) + if ( nav.Type == ETokType::Capture_Start ) { - if (template_level != 0 ) - ++ capture_level; + if ( template_level != 0 ) + ++capture_level; else break; } - if ( template_level != 0 && nav.Type == ETokType::Capture_End) - -- capture_level; + if ( template_level != 0 && nav.Type == ETokType::Capture_End ) + --capture_level; } } @@ -9025,32 +9022,32 @@ namespace parser break; } - -- idx; + --idx; Token tok_right = tokens[idx]; Token tok_left = NullToken; - if (tok_right.Type != TokType::Identifier) + if ( tok_right.Type != TokType::Identifier ) { // We're not dealing with a constructor if there is no identifier right before the opening of a parameter's scope. return result; } - -- idx; + --idx; tok_left = tokens[idx]; // ... bool possible_destructor = false; - if ( tok_left.Type == TokType::Operator && tok_left.Text[0] == '~') + if ( tok_left.Type == TokType::Operator && tok_left.Text[0] == '~' ) { possible_destructor = true; - -- idx; + --idx; tok_left = tokens[idx]; } if ( tok_left.Type != TokType::Access_StaticSymbol ) return result; - -- idx; + --idx; tok_left = tokens[idx]; // ... :: @@ -9059,37 +9056,38 @@ namespace parser s32 template_level = 0; while ( idx != tokens.Idx ) { - if (tok_left.Text[ 0 ] == '<') - ++ template_level; + if ( tok_left.Text[0] == '<' ) + ++template_level; - if (tok_left.Text[ 0 ] == '>') - -- template_level; - if (tok_left.Type == TokType::Operator && tok_left.Text[1] == '>') - -- template_level; + if ( tok_left.Text[0] == '>' ) + --template_level; + if ( tok_left.Type == TokType::Operator && tok_left.Text[1] == '>' ) + --template_level; - if ( template_level != 0 && tok_left.Type == ETokType::Capture_Start) - ++ capture_level; + if ( template_level != 0 && tok_left.Type == ETokType::Capture_Start ) + ++capture_level; - if ( template_level != 0 && tok_left.Type == ETokType::Capture_End) - -- capture_level; + if ( template_level != 0 && tok_left.Type == ETokType::Capture_End ) + --capture_level; - if ( capture_level == 0 && template_level == 0 && tok_left.Type == TokType::Identifier ) + if ( capture_level == 0 && template_level == 0 && tok_left.Type == TokType::Identifier ) break; - -- idx; + --idx; tok_left = tokens[idx]; } bool is_same = str_compare( tok_right.Text, tok_left.Text, tok_right.Length ) == 0; - if (tok_left.Type == TokType::Identifier && is_same) + if ( tok_left.Type == TokType::Identifier && is_same ) { // We have found the pattern we desired - if (possible_destructor) + if ( possible_destructor ) { // :: ~ ( result = parse_destructor( specifiers ); } - else { + else + { // :: ( result = parse_constructor( specifiers ); } @@ -9125,7 +9123,22 @@ namespace parser return { nullptr, 0, TokType::Invalid }; } - if ( currtok.Type == TokType::Operator && currtok.Text[ 0 ] == '*' && currtok.Length == 1 ) + if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' ) + { + bool is_destructor = str_compare( Context.Scope->Prev->ProcName, "parse_destructor" ) == 0; + if ( is_destructor ) + { + name.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)name.Text; + Context.pop(); + return name; + } + + log_failure( "Error, had a ~ operator after %S but not a destructor\n%s", ETokType::to_str( prevtok.Type ), Context.to_string() ); + Context.pop(); + return { nullptr, 0, TokType::Invalid }; + } + + if ( currtok.Type == TokType::Operator && currtok.Text[0] == '*' && currtok.Length == 1 ) { if ( possible_member_function ) *possible_member_function = true; @@ -9138,21 +9151,6 @@ namespace parser } } - if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' ) - { - bool is_destructor = str_compare( Context.Scope->Prev->ProcName, "parse_destructor" ) == 0; - if (is_destructor) - { - name.Length = ( ( sptr )prevtok.Text + prevtok.Length ) - ( sptr )name.Text; - Context.pop(); - return name; - } - - log_failure( "Error, had a ~ operator after %S but not a destructor\n%s", ETokType::to_str( prevtok.Type ), Context.to_string() ); - Context.pop(); - return { nullptr, 0, TokType::Invalid }; - } - if ( currtok.Type != TokType::Identifier ) { log_failure( "Error, expected static symbol identifier, not %s\n%s", ETokType::to_str( currtok.Type ), Context.to_string() ); @@ -9160,7 +9158,7 @@ namespace parser return { nullptr, 0, TokType::Invalid }; } - name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; + name.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)name.Text; eat( TokType::Identifier ); //