31. Aura HUD (plus other stuff)

- Enabled a few more plugins
- Added clang formatting straight from the GasaGen cpp.
- Setup auto-generation of the DevOptionsCache
- Messed around with generating widgettree hiearchy from template widget
This commit is contained in:
2024-04-21 09:51:51 -04:00
parent 6058e8af01
commit 18bb578c97
73 changed files with 2778 additions and 1560 deletions
+43
View File
@@ -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
+2
View File
@@ -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
+19
View File
@@ -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
}
+1 -1
View File
@@ -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"
},
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+40
View File
@@ -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
}
]
}
@@ -36,6 +36,7 @@ void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMan
void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const
{
Super::GetLifetimeReplicatedProps( OutLifetimeProps );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Health );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxHealth );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Mana );
@@ -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 ) );
return Prop;
}
static FGameplayAttribute GetMaxHealthAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( 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 ) );
return Prop;
}
static FGameplayAttribute GetMaxManaAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( 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();
}
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,39 +93,34 @@ 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 region UObject
void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override;
void
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;
#pragma endregion UObject
};
namespace Gasa
{
inline UGasaAttributeSet const* GetAttributeSet( UAbilitySystemComponent* ASC )
@@ -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,12 +24,15 @@ AGasaPlayerController::AGasaPlayerController()
bReplicates = true;
}
#pragma region Input
void AGasaPlayerController::Move(FInputActionValue const& ActionValue)
{
APawn* pawn = GetPawn<APawn>();
if (pawn == nullptr )
return;
// Note(Ed): I did the follow optimization for practice, they are completely unnecessary for this context.
#if 0
FVector2D AxisV = ActionValue.Get<FVector2D>();
@@ -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<ACameraMount>(CamClass, FActorSpawnParameters() );
Cam = GetWorld()->SpawnActor<ACameraMount>(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() );
SetViewTarget(Cam);
}
@@ -12,9 +12,6 @@ class GASA_API AGasaPlayerController : public APlayerController
GENERATED_BODY()
public:
#pragma region Camera
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<ACameraMount> CamClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<ACameraMount> Cam;
#pragma endregion Camera
@@ -60,6 +57,8 @@ public:
}
#pragma region PlayerController
void SpawnDefaultHUD() override;
void OnPossess(APawn* InPawn) override;
void OnUnPossess() override;
@@ -0,0 +1 @@
#include "GasaViewport.h"
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "Engine/GameViewportClient.h"
#include "GasaViewport.generated.h"
UCLASS()
class GASA_API UGasaViewport : public UGameViewportClient
{
GENERATED_BODY()
public:
};
+9
View File
@@ -35,6 +35,14 @@ public class Gasa : ModuleRules
"SlateCore",
"UMG",
});
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.AddRange( new string[] {
"UnrealEd",
"UMGEditor",
});
}
#endregion Engine
#region Plugins
@@ -66,5 +74,6 @@ public class Gasa : ModuleRules
#endregion Plugins
PublicIncludePaths.Add("Gasa");
PublicIncludePathModuleNames.Add("Gasa");
}
}
+9 -8
View File
@@ -48,6 +48,7 @@ class UGasaImage;
class UGasaOverlay;
class UGasaProgressBar;
class UGasaSizeBox;
class UUI_HostWidget;
#pragma endregion Forwards
#pragma region Logging
@@ -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,7 +155,7 @@ 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;
}
+5 -12
View File
@@ -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;
}
+13 -1
View File
@@ -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<ACameraMount> Template_PlayerCamera;
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
TSoftClassPtr<UUI_HostWidget> Template_HUD_HostUI;
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Tags")
FName Tag_GlobalPPV;
};
@@ -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;
}
+7 -3
View File
@@ -1,6 +1,5 @@
#pragma once
#include "GasaCommon.h"
// This was generated by GasaGen/GasaGen.cpp
#pragma once
#include "GasaDevOptionsCache.generated.h"
@@ -9,5 +8,10 @@ struct GASA_API FGasaDevOptionsCache
{
GENERATED_BODY()
UPROPERTY()
UClass* Template_PlayerCamera;
UPROPERTY()
UClass* Template_HUD_HostUI;
void CachedDevOptions();
};
@@ -2,7 +2,7 @@
#include "Blueprint/GameViewportSubsystem.h"
#include "GasaViewport.generated.h"
#include "GasaViewportSubsystem.generated.h"
UCLASS()
class GASA_API UGasaViewportSubsystem : public UGameViewportSubsystem
-9
View File
@@ -1,9 +0,0 @@
// Don't keep this included anywhere
// Purely for inspection purposes
#include "GasaCommon.h"
void test()
{
UObject::StaticClass()->PropertiesSize
}
+1
View File
@@ -0,0 +1 @@
#include "GasaCanvas.h"
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "Engine/Canvas.h"
#include "GasaCanvas.generated.h"
UCLASS()
class GASA_API UGasaCanvas : public UCanvas
{
GENERATED_BODY()
public:
};
@@ -0,0 +1 @@
#include "GasaCanvasPanel.h"
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "Components/CanvasPanel.h"
#include "GasaCanvasPanel.generated.h"
UCLASS()
class GASA_API UGasaCanvasPanel : public UCanvasPanel
{
GENERATED_BODY()
public:
};
+31
View File
@@ -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<UUI_HostWidget>( 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
+25
View File
@@ -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<UUI_HostWidget> HostWidget;
#pragma region HUD
void ShowHUD() override;
#pragma endregion HUD
#pragma region Actor
void BeginPlay() override;
#pragma endregion Actor
};
@@ -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
+6
View File
@@ -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
};
+303
View File
@@ -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<UWidget>(pUWidget, this);
UPanelWidget *pNewUPanelWidget = Cast<UPanelWidget>(pNewWidget);
if (pNewUPanelWidget)
{
const TArray<UPanelSlot*>& slots = pNewUPanelWidget->GetSlots();
for (int32 iSlotNum = 0; iSlotNum < slots.Num(); ++iSlotNum)
{
slots[iSlotNum]->Content = nullptr;
}
pNewUPanelWidget->ClearChildren();
UPanelWidget *pUPanelWidget = Cast<UPanelWidget>(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<UHorizontalBoxSlot>(pUPanelSlot);
if (pNewUHorizontalBoxSlot)
{
UHorizontalBoxSlot *pUHorizontalBoxSlot = Cast<UHorizontalBoxSlot>(pChildUWidget->Slot);
pNewUHorizontalBoxSlot->SetHorizontalAlignment(pUHorizontalBoxSlot->HorizontalAlignment);
pNewUHorizontalBoxSlot->SetVerticalAlignment(pUHorizontalBoxSlot->VerticalAlignment);
}
USizeBoxSlot *pNewUSizeBoxSlot = Cast<USizeBoxSlot>(pUPanelSlot);
if (pNewUSizeBoxSlot)
{
USizeBoxSlot *pUSizeBoxSlot = Cast<USizeBoxSlot>(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<UWidgetBlueprintGeneratedClass>(LooseParent);
UWidgetBlueprintGeneratedClass* WBG_Class = Cast<UWidgetBlueprintGeneratedClass>(GetClass());
if (WBG_ParentClass == nullptr)
return;
if (WBG_Class == nullptr)
return;
UPackage* Package = WBG_Class->GetPackage();
UWidgetBlueprint* BP = Cast<UWidgetBlueprint>(Package->FindAssetInPackage());
UWidgetTree* WT = BP->WidgetTree;
UPackage* UserParentPackage = WBG_ParentClass->GetPackage();
UWidgetBlueprint* UserParentBP = Cast<UWidgetBlueprint>(UserParentPackage->FindAssetInPackage());
UWidgetTree* UserParentWT = UserParentBP->WidgetTree;
TArray<UWidget*> UserParentWidgets;
UserParentWT->GetAllWidgets(UserParentWidgets);
for (UWidget* UserParentWidget : UserParentWidgets)
{
UWidget* OldWidget = nullptr;
UWidget* Widget = WT->FindWidget(UserParentWidget->GetFName());
TArray<UWidget*> Children;
UPanelWidget* Parent = nullptr;
if (Widget == nullptr)
{
if (UserParentWidget->GetClass()->IsChildOf(UUserWidget::StaticClass()))
Widget = CreateWidget<UUserWidget>(WT, UserParentWidget->GetClass(), UserParentWidget->GetFName());
else
Widget = NewObject<UWidget>(WT, UserParentWidget->GetClass(), UserParentWidget->GetFName(), RF_Transactional, UserParentWidget);
if (WT->RootWidget == nullptr)
{
WT->RootWidget = Widget;
}
else
{
Parent = WT->FindWidget<UPanelWidget>(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<UPanelWidget>(Widget);
if (Panel)
{
Children = Panel->GetAllChildren();
}
OldWidget = Widget;
Widget = DuplicateObject<UWidget>(UserParentWidget, WT, UserParentWidget->GetFName());
}
UPanelWidget* NewPanel = Cast<UPanelWidget>(Widget);
if (NewPanel)
{
const TArray<UPanelSlot*>& 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<UScaleBoxSlot>(PSlot);
UScrollBoxSlot* SlotScroll = Cast<UScrollBoxSlot>(PSlot);
UOverlaySlot* SlotOverlay = Cast<UOverlaySlot>(PSlot);
UHorizontalBoxSlot* SlotHB = Cast<UHorizontalBoxSlot>(PSlot);
USizeBoxSlot* SlotSB = Cast<USizeBoxSlot>(PSlot);
UVerticalBoxSlot* SlobVB = Cast<UVerticalBoxSlot>(PSlot);
if (SlotOverlay)
{
UOverlay* UPW_ParentOverlay = Cast<UOverlay>(UserParentWidget->GetParent());
UOverlaySlot* ParentSlot = Cast<UOverlaySlot>(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<UPanelWidget>(Widget)->AddChild(Child);
UScaleBoxSlot* SlotScale = Cast<UScaleBoxSlot>(PSlot);
UScrollBoxSlot* SlotScroll = Cast<UScrollBoxSlot>(PSlot);
UOverlaySlot* SlotOverlay = Cast<UOverlaySlot>(PSlot);
UHorizontalBoxSlot* SlotHB = Cast<UHorizontalBoxSlot>(PSlot);
USizeBoxSlot* SlotSB = Cast<USizeBoxSlot>(PSlot);
UVerticalBoxSlot* SlobVB = Cast<UVerticalBoxSlot>(PSlot);
// I'm not entirely sure if this is possible this way...
if (SlotOverlay)
{
UOverlay* ParentOverlay = Cast<UOverlay>(OldWidget->GetParent());
UOverlaySlot* ParentSlot = Cast<UOverlaySlot>(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<UUserWidget>())
{
#if WITH_EDITOR
SetDesignerFlags(OwningUserWidget->GetDesignerFlags());
#endif
SetPlayerContext(OwningUserWidget->GetPlayerContext());
}
UWidgetBlueprintGeneratedClass* BGClass = Cast<UWidgetBlueprintGeneratedClass>(GetClass());
// Only do this if this widget is of a blueprint class
if (BGClass)
{
BGClass->InitializeWidget(this);
}
else
{
InitializeNativeClassData();
}
if ( WidgetTree == nullptr )
{
WidgetTree = NewObject<UWidgetTree>(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<UWidgetBlueprintGeneratedClass>(LooseParent);
UPackage* UserParentPackage = WBG_ParentClass->GetPackage();
UWidgetBlueprint* UserParentBP = Cast<UWidgetBlueprint>(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<UWidgetBlueprintGeneratedClass>(LooseParent);
if (WBG_ParentClass == nullptr)
return;
UPackage* UserParentPackage = WBG_ParentClass->GetPackage();
UWidgetBlueprint* UserParentBP = Cast<UWidgetBlueprint>(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<UWidgetBlueprintGeneratedClass>(LooseParent);
UPackage* UserParentPackage = WBG_ParentClass->GetPackage();
UWidgetBlueprint* UserParentBP = Cast<UWidgetBlueprint>(UserParentPackage->FindAssetInPackage());
UWidgetTree* UserParentWT = UserParentBP->WidgetTree;
UserParentBP->OnCompiled().AddLambda( [this](UBlueprint* BP) {
if (this)
{
this->GenerateParentHierarchyFromLooseParent();
}
});
}
#endif
}
+22
View File
@@ -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<UGasaUserWidget> LooseParent;
UPROPERTY(BlueprintReadOnly)
TObjectPtr<UObject> 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
};
+91 -10
View File
@@ -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<UWidgetBlueprintGeneratedClass>(GetClass());
UPackage* Package = WBG_Class->GetPackage();
UWidgetBlueprint* AssetBP = Cast<UWidgetBlueprint>(Package->FindAssetInPackage());
UWidgetTree* WT = AssetBP->WidgetTree;
UWidget* AssetRoot = AssetBP->WidgetTree->RootWidget;
UGasaSizeBox* Asset_SB = WT->FindWidget<UGasaSizeBox>("Root");
UGasaOverlay* Asset_Overlay = WT->FindWidget<UGasaOverlay>("Overlay");
UGasaImage* Asset_Bezel = WT->FindWidget<UGasaImage>("Bezel");
UGasaImage* Asset_Glass = WT->FindWidget<UGasaImage>("Glass");
UGasaProgressBar* Asset_Bar = WT->FindWidget<UGasaProgressBar>("Bar");
if (Root_SB == nullptr)
Asset_SB = WT->ConstructWidget<UGasaSizeBox>(UGasaSizeBox::StaticClass(), FName("Root_SB"));
if (Overlay == nullptr)
Asset_Overlay = WT->ConstructWidget<UGasaOverlay>(UGasaOverlay::StaticClass(), FName("Overlay"));
if (Bezel == nullptr)
Asset_Bezel = WT->ConstructWidget<UGasaImage>(UGasaImage::StaticClass(), FName("Bezel"));
if (Glass == nullptr)
Asset_Glass = WT->ConstructWidget<UGasaImage>(UGasaImage::StaticClass(), FName("Glass"));
if (Bar == nullptr)
Asset_Bar = WT->ConstructWidget<UGasaProgressBar>(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
#if 0
void UGlobeProgressBar::UpdateSize()
#pragma region Widget
void UGlobeProgressBar::SynchronizeProperties()
{
Super::SynchronizeProperties();
}
void UGlobeProgressBar::UpdateBackground()
void UGlobeProgressBar::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
}
#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<UWidgetBlueprintGeneratedClass>(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
+27 -17
View File
@@ -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 = (BindWidget), Category="Globe")
UGasaImage* BG;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe")
UGasaOverlay* Overlay;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category="Globe")
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidgetOptional), Category="Globe")
UGasaImage* Bezel;
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);
#pragma endregion Bindings
#if 0
UFUNCTION(BlueprintCallable, Category="Globe")
void UpdateSize();
// UGlobeProgressBar(FObjectInitializer const& ObjectInitializer);
UFUNCTION(BlueprintCallable, Category="Globe")
void UpdateBackground();
#endif
#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
};
+1
View File
@@ -0,0 +1 @@
#include "UI_HostWidget.h"
+13
View File
@@ -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
};
+1 -1
View File
@@ -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:
+10 -1
View File
@@ -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");
}
}
@@ -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<UObject> Object : LayoutBuilder.GetSelectedObjects())
{
if ( ! Object.IsValid())
return;
Globe = Cast<UGlobeProgressBar>(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<IPropertyHandle>
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<IPropertyHandle> WidgetStyle = ProgressBarStyleHandle->GetChildHandle("WidgetStyle");
// if ( ! WidgetStyle.IsValid())
// return;
IDetailPropertyRow& ProgressBarRow = LayoutBuilder.AddPropertyToCategory(ProgressBarStyle);
FDetailWidgetRow& RowWidget = ProgressBarRow.CustomWidget();
{
FDetailWidgetDecl& RowNameWidget = RowWidget.NameContent();
{
TSharedRef<STextBlock>
TextBlock = SNew(STextBlock);
TextBlock->SetText(FText::FromString(TEXT("Bar Fill Material")));
TextBlock->SetFont(LayoutBuilder.GetDetailFont());
RowNameWidget.Widget = TextBlock;
}
FDetailWidgetDecl& RowValueWidget = RowWidget.ValueContent();
TSharedRef<SHorizontalBox> HBox = SNew(SHorizontalBox);
{
SHorizontalBox::FSlot::FSlotArguments ThumbnailSlot = SHorizontalBox::Slot();
{
TSharedRef<SBox> 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<SObjectPropertyEntryBox> 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<UBaseWidgetBlueprint>(Globe->WidgetGeneratedBy);
if (GlobeBP != nullptr)
{
GlobeBP->Modify();
UObject* CDO = GlobeBP->GeneratedClass->GetDefaultObject();
UGlobeProgressBar* GlobeCDO = Cast<UGlobeProgressBar>(CDO);
UWidget* PossibleWidget = Cast<UBaseWidgetBlueprint>(GlobeBP)->WidgetTree->FindWidget("Bar");
if (PossibleWidget)
{
UGasaProgressBar* BarWidget = Cast<UGasaProgressBar>(PossibleWidget);
BarWidget->SetWidgetStyle(Style);
GlobeBP->MarkPackageDirty();
}
else // Its parent is it.
{
UWidgetBlueprintGeneratedClass* Parent = Cast<UWidgetBlueprintGeneratedClass>(GlobeBP->ParentClass);
UPackage* Pkg = Parent->GetOuterUPackage();
PossibleWidget = Parent->GetWidgetTreeArchetype()->FindWidget("Bar");
if (PossibleWidget)
{
GlobeCDO->Bar = GlobeCDO->WidgetTree->ConstructWidget<UGasaProgressBar>( 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
@@ -0,0 +1,14 @@
#pragma once
#include "IDetailCustomization.h"
class FGlobeProgressBarDetails : public IDetailCustomization
{
public:
static TSharedRef<IDetailCustomization> MakeInstance() { return MakeShareable(new FGlobeProgressBarDetails); }
void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
static bool CheckAsset(FAssetData const& Asset);
TSharedPtr<FAssetThumbnail> Thumbnail;
};
+11 -1
View File
@@ -8,12 +8,22 @@ public class GasaEditor : ModuleRules
#region Engine
PrivateIncludePathModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
});
PrivateDependencyModuleNames.AddRange(new string[] {
"Core",
"Engine",
"CoreUObject",
"PropertyEditor",
"SlateCore",
"Slate",
"UMG",
"UnrealEd",
});
#endregion Engine
PublicIncludePathModuleNames.Add("Gasa");
PublicIncludePaths.Add("GasaEditor");
PrivateDependencyModuleNames.Add("Gasa");
}
}
@@ -0,0 +1,3 @@
#include "GasaEditorCommon.h"
DEFINE_LOG_CATEGORY(LogGasaEditor);
@@ -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
+12 -1
View File
@@ -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<FPropertyEditorModule>("PropertyEditor");
PropertyEditor.RegisterCustomClassLayout( UGlobeProgressBar::StaticClass()->GetFName()
, FOnGetDetailCustomizationInstance::CreateStatic(& FGlobeProgressBarDetails::MakeInstance)
);
}
void FGasaEditorModule::ShutdownModule()
{
if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
{
FPropertyEditorModule& PropertyEditor = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyEditor.UnregisterCustomClassLayout(UGlobeProgressBar::StaticClass()->GetFName());
}
}
+57 -82
View File
@@ -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 <process.h>
#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 );
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(");
{
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 );
}
// 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_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_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_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_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));
// ue_parse_testing();
StrC str_gasa_api = txt("GASA_API");
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();
gen_FGasaDevOptionsCache();
// One offs
if (0)
{
ue_parse_testing();
swap_SBlueprintActionMenu_Construct();
}
return 0;
}
+88 -6
View File
@@ -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
}
@@ -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<FBlueprintEditor> InEditor )
{
@@ -255,19 +264,22 @@ void swap_SBlueprintActionMenu_Construct()
using namespace ECode;
case Function:
CodeFn function_def = code.cast<CodeFn>();
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();
format_file(path_SBlueprintActionMenuCpp);
}
@@ -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<CodeVar> GasaDevOptions_UPROPERTIES = Array<CodeVar>::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<CodeClass>();
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<CodeVar>());
}
}
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 {
<body>
};
)));
}
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<CodeInclude> GasaDevOptions_Includes = Array<CodeInclude>::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<CodeInclude>() );
}
}
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(
<property> = DevOpts-> <property>.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();
<cached_property_assignments>
Tag_GlobalPPV = DevOpts->Tag_GlobalPPV;
})
));
source.print(CachedDevOptions);
source.write();
format_file( path_module_gasa "GasaDevOptionsCache.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<StringCached> properties );
void def_attribute_field_on_reps ( CodeBody body, Array<StringCached> 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<StringCached> properties )
{
for ( String property : properties )
{
#pragma push_macro(FORCEINLINE)
#undef FORCEINLINE
body.append( code_fmt( "property", (StrC)property,
stringize(
FORCEINLINE float Get<property>() const
@@ -213,7 +222,6 @@ void def_attribute_field_value_getters( CodeBody body, Array<StringCached> prope
return <property>.GetCurrentValue();
}
)));
#pragma pop_macro(FORCEINLINE)
}
}
@@ -267,3 +275,4 @@ void impl_attribute_fields( CodeBody body, StrC class_name, Array<StringCached>
body.append( field_impl );
}
}
#pragma pop_macro("FORCEINLINE")
@@ -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 });
-1
View File
@@ -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 );
+76 -73
View File
@@ -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,10 +1590,12 @@ 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 );
}
@@ -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,7 +2041,7 @@ 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 )
result.append_fmt( " = %S;", ast->Body.to_string() );
@@ -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() );
@@ -3454,14 +3457,17 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
}
}
break;
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;
@@ -3843,7 +3849,7 @@ CodeClass def_class(
result->Type = Class;
result->Body = body;
result->Body->Parent = result;
result->Body->Parent = result; // TODO(Ed): Review this?
}
else
{
@@ -3876,11 +3882,14 @@ 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();
result->Type = Preprocess_Define;
@@ -5652,14 +5661,10 @@ 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" )
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,14 +5763,14 @@ 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
};
@@ -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<StrC>& defines, Token& token )
{
char const* hash = scanner;
Tokens.append( { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } );
@@ -7886,7 +7890,6 @@ namespace parser
internal neverinline CodeBody parse_class_struct_body( TokType which, Token name )
{
using namespace ECode;
push_scope();
eat( TokType::BraceCurly_Open );
@@ -8319,9 +8322,7 @@ namespace parser
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
// <enum> <type_identifier> : <identifier>;
@@ -8355,9 +8356,7 @@ namespace parser
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() );
Context.pop();
@@ -8441,8 +8440,7 @@ namespace parser
return define;
}
internal inline
Code parse_assignment_expression()
internal inline Code parse_assignment_expression()
{
Code expr = { nullptr };
@@ -8970,8 +8968,7 @@ 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 };
@@ -9089,7 +9086,8 @@ namespace parser
// <Name> :: ~<Name> (
result = parse_destructor( specifiers );
}
else {
else
{
// <Name> :: <Name> (
result = parse_constructor( specifiers );
}
@@ -9125,19 +9123,6 @@ namespace parser
return { nullptr, 0, TokType::Invalid };
}
if ( currtok.Type == TokType::Operator && currtok.Text[ 0 ] == '*' && currtok.Length == 1 )
{
if ( possible_member_function )
*possible_member_function = true;
else
{
log_failure( "Found a member function pointer identifier but the parsing context did not expect it\n%s", Context.to_string() );
Context.pop();
return { nullptr, 0, TokType::Invalid };
}
}
if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' )
{
bool is_destructor = str_compare( Context.Scope->Prev->ProcName, "parse_destructor" ) == 0;
@@ -9153,6 +9138,19 @@ namespace parser
return { nullptr, 0, TokType::Invalid };
}
if ( currtok.Type == TokType::Operator && currtok.Text[0] == '*' && currtok.Length == 1 )
{
if ( possible_member_function )
*possible_member_function = true;
else
{
log_failure( "Found a member function pointer identifier but the parsing context did not expect it\n%s", 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() );
@@ -9484,7 +9482,13 @@ namespace parser
}
}
}
break;
}
if ( op == Invalid )
{
log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() );
Context.pop();
return CodeInvalid;
}
if ( ! was_new_or_delete )
@@ -9704,8 +9708,7 @@ namespace parser
// or < ... >
}
#define CheckEndParams() \
(use_template_capture ? (currtok.Text[ 0 ] != '>') : (currtok.Type != TokType::Capture_End))
#define CheckEndParams() ( use_template_capture ? ( currtok.Text[0] != '>' ) : ( currtok.Type != TokType::Capture_End ) )
// Ex: Unreal has this type of macro: vvvvvvvvv
// COREUOBJECT_API void CallFunction( FFrame& Stack, RESULT_DECL, UFunction* Function );
@@ -9855,11 +9858,7 @@ namespace parser
s32 capture_level = 0;
s32 template_level = 0;
while ( left
&& currtok.Type != TokType::Comma
&& template_level >= 0
&& CheckEndParams()
|| capture_level > 0 || template_level > 0 )
while ( left && currtok.Type != TokType::Comma && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 )
{
if ( currtok.Text[0] == '<' )
++template_level;
@@ -10445,7 +10444,9 @@ namespace parser
}
// <Virtual Specifier>
Token prefix_identifier = parse_identifier();
Token prefix_identifier = NullToken;
if ( is_in_global_nspace )
prefix_identifier = parse_identifier();
if ( left && currtok.Text[0] == '~' )
eat( TokType::Operator );
@@ -10682,7 +10683,6 @@ namespace parser
}
// <Name> = <Expression>
// Unreal UMETA macro support
if ( currtok.Type == TokType::Preprocess_Macro )
{
@@ -11935,8 +11935,11 @@ namespace parser
}
}
else
type = parse_type( false, &is_function );
{
bool from_template = false;
type = parse_type( from_template, &is_function );
// <ModuleFalgs> typedef <UnderlyingType>
}
if ( check( TokType::Identifier ) )
{
+35 -1
View File
@@ -1617,7 +1617,6 @@ struct Array
mem_move( target + 1, target, ( header->Num - idx ) * sizeof( Type ) );
header->Num++;
Data[ idx ] = item;
return true;
}
@@ -2082,6 +2081,11 @@ struct StrC
sw Len;
char const* Ptr;
char const& operator[]( sw index ) const
{
return Ptr[index];
}
operator char const*() const
{
return Ptr;
@@ -2165,6 +2169,18 @@ struct String
return true;
}
static bool are_equal( String lhs, StrC rhs )
{
if ( lhs.length() != (rhs.Len - 1) )
return false;
for ( sw idx = 0; idx < lhs.length(); ++idx )
if ( lhs[idx] != rhs[idx] )
return false;
return true;
}
bool make_space_for( char const* str, sw add_len );
bool append( char c )
@@ -2233,6 +2249,24 @@ struct String
get_header().Length = 0;
}
b32 starts_with( StrC substring ) const
{
if (substring.Len > length())
return false;
b32 result = str_compare(Data, substring.Ptr, substring.Len ) == 0;
return result;
}
b32 starts_with( String substring ) const
{
if (substring.length() > length())
return false;
b32 result = str_compare(Data, substring, substring.length() - 1 ) == 0;
return result;
}
String duplicate( AllocatorInfo allocator ) const
{
return make_length( allocator, Data, length() );
+3 -3
View File
@@ -903,6 +903,7 @@ struct AST_POD
union
{
AST* Macro; // Parameter
AST* BitfieldSize; // Variable (Class/Struct Data Member)
AST* Params; // Constructor, Function, Operator, Template, Typename
};
@@ -2625,11 +2626,11 @@ struct AST_Param
struct
{
char _PAD_PROPERTIES_1_[ sizeof( AST* ) * 3 ];
char _PAD_PROPERTIES_2_[sizeof( AST* ) * 3];
CodeType ValueType;
Code Macro;
Code Value;
char _PAD_PROPERTIES_2_[ sizeof( AST* ) ];
char _PAD_PROPERTIES_3_[sizeof( AST* )];
};
};
@@ -6381,7 +6382,6 @@ extern CodeAttributes attrib_api_import;
extern Code module_global_fragment;
extern Code module_private_fragment;
// Exposed, but this is really used for parsing.
extern Code fmt_newline;
extern CodePragma pragma_once;
+15 -12
View File
@@ -6,7 +6,7 @@ AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Left
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: true
PadOperators: true
@@ -24,17 +24,16 @@ AlignConsecutiveMacros:
AcrossComments: false
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortLambdasOnASingleLine: None
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
@@ -60,16 +59,17 @@ BraceWrapping:
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BeforeLambdaBody: false
BeforeWhile: false
BreakAfterAttributes: Always
BreakArrays: true
# BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: true
@@ -79,7 +79,7 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: true
ColumnLimit: 160
ColumnLimit: 240
CompactNamespaces: true
@@ -92,6 +92,7 @@ Cpp11BracedListStyle: false
DeriveLineEnding: true
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
@@ -102,7 +103,7 @@ IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentPPDirectives: BeforeHash
IndentRequires: true
IndentWidth: 4
IndentWrappedFunctionNames: true
@@ -126,9 +127,9 @@ ReferenceAlignment: Left
ReflowComments: true
# RequiresExpressionIndentation: OuterScope
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 40
@@ -163,7 +164,9 @@ SpacesInLineCommentPrefix:
SpacesInParentheses: true
SpacesInSquareBrackets: false
Standard: c++17
Standard: c++20
StatementMacros: ['UPROPERTY', 'UFUNCTION', 'UCLASS', 'USTRUCT', 'UENUM', 'UINTERFACE', 'GENERATED_BODY']
TabWidth: 4
-2
View File
@@ -1,5 +1,3 @@
Clear-Host
$path_scripts = $PSScriptRoot
$path_helpers = join-path $path_scripts 'helpers'
$path_root = split-path -Parent -Path $path_scripts
+1 -13
View File
@@ -1,5 +1,3 @@
Clear-Host
$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
@@ -91,7 +89,7 @@ build-gengasa
function run-gengasa
{
Push-Location $path_project
Push-Location $path_root
if ( Test-Path( $exe_gasagen ) ) {
write-host "`nRunning GasaGen"
$time_taken = Measure-Command { & $exe_gasagen
@@ -102,15 +100,5 @@ function run-gengasa
write-host "`GasaGen completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
$path_AbilitySystem = join-path $path_gasa 'AbilitySystem'
$include = @(
'GasaAttributeSet.h', 'GasaAttributeSet.cpp'
)
format-cpp $path_AbilitySystem $include $null
$path_KismetPrivate = 'C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\Kismet\Private\'
$include = @( 'SBlueprintActionMenu.cpp' )
format-cpp $path_KismetPrivate $include $null
}
run-gengasa
+8 -8
View File
@@ -171,8 +171,8 @@ if ( $vendor -match "clang" )
$map = join-path $path_output (split-path $map -Leaf)
# This allows dll reloads at runtime to work (jankily, use below if not interested)
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
# $pdb = $binary -replace '\.(exe|dll)$', ".pdb"
# $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
$pdb = $binary -replace '\.(exe|dll)$', ".pdb"
$compiler_args += @(
$flag_no_color_diagnostics,
@@ -250,8 +250,8 @@ if ( $vendor -match "clang" )
$map = join-path $path_output (split-path $map -Leaf)
# This allows dll reloads at runtime to work (jankily, use below if not interested)
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
# $pdb = $binary -replace '\.(exe|dll)$', ".pdb"
# $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
$pdb = $binary -replace '\.(exe|dll)$', ".pdb"
$compiler_args += @(
$flag_no_color_diagnostics,
@@ -369,8 +369,8 @@ if ( $vendor -match "msvc" )
$map = join-path $path_output (split-path $map -Leaf)
# This allows dll reloads at runtime to work (jankily, use below if not interested)
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
# $pdb = $binary -replace '\.(exe|dll)$', ".pdb"
# $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
$pdb = $binary -replace '\.(exe|dll)$', ".pdb"
$compiler_args += @(
$flag_nologo,
@@ -455,8 +455,8 @@ if ( $vendor -match "msvc" )
$map = join-path $path_output (split-path $map -Leaf)
# This allows dll reloads at runtime to work (jankily, use below if not interested)
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
# $pdb = $binary -replace '\.(exe|dll)$', ".pdb"
# $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
$pdb = $binary -replace '\.(exe|dll)$', ".pdb"
$compiler_args += @(
$flag_nologo,