Compare commits

...

3 Commits

Author SHA1 Message Date
Ed_
eef7709fc6 update gitignore 2024-10-24 20:29:00 -04:00
Ed_
0f7c51b7b8 GasaGen changes (renames to files, added more changes to ue editor slate UI) 2024-10-24 20:28:52 -04:00
Ed_
60a4128df4 Fixes to gencpp 2024-10-24 20:27:52 -04:00
13 changed files with 1148 additions and 32 deletions

9
.gitignore vendored
View File

@ -4,11 +4,14 @@ Project/.idea
Project/.vs Project/.vs
Project/.vsconfig Project/.vsconfig
Project/Binaries !Project/Binaries/Win64/*
Project/Binaries/GasaGen.exe Project/Binaries/GasaGen.exe
Project/Binaries/GasaGen.map Project/Binaries/GasaGen.map
Project/Binaries/GasaGen.obj Project/Binaries/GasaGen.obj
Project/Binaries/vc140.pdb Project/Binaries/GasaGen.raddbgi
Project/Binaries/GasaGen.rdi
# Project/Binaries/vc140.pdb
!Project/Binaries/GasaEditor.target
Project/Intermediate Project/Intermediate
@ -37,3 +40,5 @@ Project/Saved/SourceControl
GasaGen_*.pdb GasaGen_*.pdb
Project/Content/ Project/Content/
.vs
.vs

View File

@ -1,4 +1,4 @@
#include "GasaGen_AttributeSets.h" #include "AttributeSets.h"
#include "GasaGen_Common.h" #include "GasaGen_Common.h"
#include "Gasa/AbilitySystem/GasaAbilitySystem.h" #include "Gasa/AbilitySystem/GasaAbilitySystem.h"

View File

@ -0,0 +1,279 @@
// Used in the GasaGen.cpp translation unit
#include "GasaGen_Common.h"
constexpr StrC SBlueprintActionMenu_Construct_Replacement = txt(R"(
void SBlueprintActionMenu::Construct( const FArguments& InArgs, TSharedPtr<FBlueprintEditor> InEditor )
{
bActionExecuted = false;
this->GraphObj = InArgs._GraphObj;
this->DraggedFromPins = InArgs._DraggedFromPins;
this->NewNodePosition = InArgs._NewNodePosition;
this->OnClosedCallback = InArgs._OnClosedCallback;
this->bAutoExpandActionMenu = InArgs._AutoExpandActionMenu;
this->EditorPtr = InEditor;
this->OnCloseReasonCallback = InArgs._OnCloseReason;
// Generate the context display; showing the user what they're picking something for
//@TODO: Should probably be somewhere more schema-sensitive than the graph panel!
FSlateColor TypeColor;
FString TypeOfDisplay;
const FSlateBrush* ContextIcon = nullptr;
if (DraggedFromPins.Num() == 1)
{
UEdGraphPin* OnePin = DraggedFromPins[0];
const UEdGraphSchema* Schema = OnePin->GetSchema();
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
if (!Schema->IsA(UEdGraphSchema_K2::StaticClass()) || !K2Schema->IsExecPin(*OnePin))
{
// Get the type color and icon
TypeColor = Schema->GetPinTypeColor(OnePin->PinType);
ContextIcon = FAppStyle::GetBrush( OnePin->PinType.IsArray() ? TEXT("Graph.ArrayPin.Connected") : TEXT("Graph.Pin.Connected") );
}
}
FBlueprintActionContext MenuContext;
ConstructActionContext(MenuContext);
TSharedPtr<SWidget> AddImportTargetContent = SNullWidget::NullWidget;
if (GetDefault<UBlueprintEditorSettings>()->bEnableNamespaceImportingFeatures)
{
SAssignNew(AddImportTargetContent, SBox)
.ToolTipText(LOCTEXT("ImportActionLabelTooltip", "Choose a namespace to import and load additional actions."))
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(LOCTEXT("ImportActionButtonLabel", "Import Actions From:"))
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(4.f, 0.f)
[
SNew(SBlueprintNamespaceEntry)
.AllowTextEntry(false)
.OnNamespaceSelected(this, &SBlueprintActionMenu::OnNamespaceSelectedForImport)
.OnGetNamespacesToExclude(this, &SBlueprintActionMenu::OnGetNamespacesToExcludeFromImportMenu)
.ExcludedNamespaceTooltipText(LOCTEXT("CannotSelectNamespaceForImport", "This namespace has already been imported by this Blueprint."))
]
];
}
TSharedPtr<SComboButton> TargetContextSubMenuButton;
// @TODO: would be nice if we could use a checkbox style for this, and have a different state for open/closed
SAssignNew(TargetContextSubMenuButton, SComboButton)
.MenuPlacement(MenuPlacement_MenuRight)
.HasDownArrow(false)
.ButtonStyle(FAppStyle::Get(), "BlueprintEditor.ContextMenu.TargetsButton")
.ContentPadding(FMargin(5))
.MenuContent()
[
SAssignNew(ContextTargetSubMenu, SBlueprintContextTargetMenu, MenuContext)
.OnTargetMaskChanged(this, &SBlueprintActionMenu::OnContextTargetsChanged)
.CustomTargetContent()
[
AddImportTargetContent.ToSharedRef()
]
];
// Build the widget layout
TSharedRef<SBox> ContentBox = SNew(SBox);
{
TSharedRef<SVerticalBox> VBox = SNew(SVerticalBox);
{
SVerticalBox::FSlot::FSlotArguments
SearchIndicator = SVerticalBox::Slot();
{
TSharedRef<SHorizontalBox> HBox = SNew(SHorizontalBox);
{
SHorizontalBox::FSlot::FSlotArguments
TypePill = SHorizontalBox::Slot();
{
TSharedRef<SImage> PillImage = SNew(SImage);
{
SImage::FArguments Args;
Args.Visibility(this, & SBlueprintActionMenu::GetTypeImageVisibility);
PillImage->SetColorAndOpacity(TypeColor);
PillImage->SetImage(ContextIcon);
PillImage->Construct(Args);
}
SHorizontalBox::FSlot* Slot; TypePill.Expose(Slot);
TypePill.AutoWidth();
TypePill.VAlign(VAlign_Center);
TypePill.Padding( FMargin(0.f, 0.f, (ContextIcon != nullptr) ? 5.f : 0.f, 0.f));
TypePill.AttachWidget(PillImage);
}
SHorizontalBox::FSlot::FSlotArguments
SearchContextDescription = SHorizontalBox::Slot();
{
TSharedRef<STextBlock> TextBlock = SNew(STextBlock);
{
STextBlock::FArguments Args;
Args.Text(this, & SBlueprintActionMenu::GetSearchContextDesc);
Args.Font(FAppStyle::GetFontStyle(FName("BlueprintEditor.ActionMenu.ContextDescriptionFont")));
Args.ToolTip(IDocumentation::Get()->CreateToolTip(
LOCTEXT("BlueprintActionMenuContextTextTooltip", "Describes the current context of the action list"),
NULL,
TEXT("Shared/Editors/BlueprintEditor"),
TEXT("BlueprintActionMenuContextText")));
Args.AutoWrapText(true);
TextBlock->Construct(Args);
}
SearchContextDescription.FillWidth(1.f);
SearchContextDescription.VAlign(VAlign_Center);
SearchContextDescription.AttachWidget(TextBlock);
}
SHorizontalBox::FSlot::FSlotArguments
ContextToggle = SHorizontalBox::Slot();
{
TSharedRef<SCheckBox> CheckBox = SNew(SCheckBox);
{
SCheckBox::FArguments Args;
Args.OnCheckStateChanged(this, & SBlueprintActionMenu::OnContextToggleChanged);
Args.IsChecked(this, & SBlueprintActionMenu::ContextToggleIsChecked);
Args.ToolTip(IDocumentation::Get()->CreateToolTip(
LOCTEXT("BlueprintActionMenuContextToggleTooltip"
, "Should the list be filtered to only actions that make sense in the current context?"),
NULL,
TEXT("Shared/Editors/BlueprintEditor"),
TEXT("BlueprintActionMenuContextToggle")));
Args.Content().SlotContent.Widget = SNew(STextBlock)
.Text(LOCTEXT("BlueprintActionMenuContextToggle", "Context Sensitive"));
CheckBox->Construct(Args);
}
ContextToggle.HAlign(HAlign_Right);
ContextToggle.VAlign(VAlign_Center);
ContextToggle.AutoWidth();
ContextToggle.AttachWidget( CheckBox );
}
SHorizontalBox::FSlot::FSlotArguments
ContextButton = SHorizontalBox::Slot();
{
ContextButton.HAlign(HAlign_Right);
ContextButton.VAlign(VAlign_Center);
ContextButton.AutoWidth();
ContextButton.Padding( FMargin( 3.f, 0.f, 0.f, 0.f ));
ContextButton.AttachWidget( TargetContextSubMenuButton.ToSharedRef() );
}
SHorizontalBox::FArguments Args = SHorizontalBox::FArguments();
Args.operator+( TypePill );
Args.operator+( SearchContextDescription );
Args.operator+( ContextToggle );
Args.operator+( ContextButton );
HBox->Construct(Args);
}
SearchIndicator.AutoHeight();
SearchIndicator.Padding( FMargin(2, 2, 2, 5));
SearchIndicator.AttachWidget(HBox);
}
SVerticalBox::FSlot::FSlotArguments
ActionList = SVerticalBox::Slot();
{
SAssignNew( GraphActionMenu, SGraphActionMenu);
SGraphActionMenu::FArguments Args;
Args.OnActionSelected(this, &SBlueprintActionMenu::OnActionSelected);
Args.OnCreateWidgetForAction(SGraphActionMenu::FOnCreateWidgetForAction::CreateSP(this, &SBlueprintActionMenu::OnCreateWidgetForAction));
Args.OnGetActionList(this, &SBlueprintActionMenu::OnGetActionList);
Args.OnCreateCustomRowExpander_Static(&CreateCustomBlueprintActionExpander);
Args.DraggedFromPins(DraggedFromPins);
Args.GraphObj(GraphObj);
GraphActionMenu->Construct(Args);
ActionList.AttachWidget( GraphActionMenu.ToSharedRef() );
}
SVerticalBox::FSlot::FSlotArguments
ProgressBar = SVerticalBox::Slot();
{
TSharedRef<SBox> Box = SNew(SBox);
{
TSharedRef<SProgressBar> Bar = SNew(SProgressBar);
{
Bar->SetBorderPadding(FVector2D( 0, 0 ));
Bar->SetPercent( TAttribute<TOptional<float>>::CreateLambda([this]()
{
return ContextMenuBuilder.IsValid() ? ContextMenuBuilder->GetPendingActionsProgress() : 0.0f;
}));
}
Box->SetContent( Bar );
Box->SetHeightOverride(2);
Box->SetVisibility(TAttribute<EVisibility>().CreateLambda([this]()
{
return ContextMenuBuilder.IsValid() && ContextMenuBuilder->GetNumPendingActions() > 0 ? EVisibility::SelfHitTestInvisible : EVisibility::Collapsed;
}));
}
ProgressBar.AutoHeight();
ProgressBar.AttachWidget(Box);
}
SVerticalBox::FArguments Args;
Args.operator+( SearchIndicator );
Args.operator+( ActionList );
Args.operator+( ProgressBar );
VBox->Construct( Args );
}
ContentBox->SetMaxDesiredWidth(500.f);
ContentBox->SetMaxDesiredHeight(650.f);
ContentBox->SetContent( VBox );
SBorder::FArguments Args;
Args.BorderImage(FAppStyle::GetBrush("Menu.Background"));
Args.Padding(5.0f);
Args.operator[](ContentBox);
SBorder::Construct(Args);
}
})");
void change_SBlueprintActionMenu_Construct()
{
#define path_SBlueprintActionMenuCpp \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\Kismet\Private\SBlueprintActionMenu.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SBlueprintActionMenuCpp );
CodeBody parsed_SBlueprintActionMenu = parse_global_body( StrC { content.size, (char const*)content.data });
CodeFn signature_to_change = parse_function( code(
void SBlueprintActionMenu::Construct( const FArguments& InArgs, TSharedPtr<FBlueprintEditor> InEditor ) {}
));
CodeBody changed_SBlueprintActionMenu = def_body(ECode::Global_Body);
for ( Code code : parsed_SBlueprintActionMenu )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
CodeFn function_def = code.cast<CodeFn>();
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/ChangeBPActionMenu.cpp")));
SBlueprintActionMenu_Changed.print(changed_SBlueprintActionMenu);
SBlueprintActionMenu_Changed.write();
format_file(path_SBlueprintActionMenuCpp, false);
}

View File

@ -0,0 +1,3 @@
#pragma once
void change_SBlueprintActionMenu_Construct();

View File

@ -0,0 +1,727 @@
#include "ChangeEditorContentList.h"
#include "GasaGen_Common.h"
#include "GasaEditorCommon.h"
constexpr StrC SAssetView_Construct_Replacement = txt(R"(
void SAssetView::Construct( const FArguments& InArgs )
{
ViewCorrelationGuid = FGuid::NewGuid();
InitialNumAmortizedTasks = 0;
TotalAmortizeTime = 0;
AmortizeStartTime = 0;
MaxSecondsPerFrame = 0.015f;
bFillEmptySpaceInTileView = InArgs._FillEmptySpaceInTileView;
FillScale = 1.0f;
bShowRedirectors = InArgs._ShowRedirectors;
bLastShowRedirectors = bShowRedirectors.Get(false);
ThumbnailHintFadeInSequence.JumpToStart();
ThumbnailHintFadeInSequence.AddCurve(0, 0.5f, ECurveEaseFunction::Linear);
UContentBrowserDataSubsystem* ContentBrowserData = IContentBrowserDataModule::Get().GetSubsystem();
ContentBrowserData->OnItemDataUpdated().AddSP(this, &SAssetView::HandleItemDataUpdated);
ContentBrowserData->OnItemDataRefreshed().AddSP(this, &SAssetView::RequestSlowFullListRefresh);
ContentBrowserData->OnItemDataDiscoveryComplete().AddSP(this, &SAssetView::HandleItemDataDiscoveryComplete);
FilterCacheID.Initialaze(ContentBrowserData);
FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
CollectionManagerModule.Get().OnAssetsAddedToCollection().AddSP( this, &SAssetView::OnAssetsAddedToCollection );
CollectionManagerModule.Get().OnAssetsRemovedFromCollection().AddSP( this, &SAssetView::OnAssetsRemovedFromCollection );
CollectionManagerModule.Get().OnCollectionRenamed().AddSP( this, &SAssetView::OnCollectionRenamed );
CollectionManagerModule.Get().OnCollectionUpdated().AddSP( this, &SAssetView::OnCollectionUpdated );
// Listen for when view settings are changed
UContentBrowserSettings::OnSettingChanged().AddSP(this, &SAssetView::HandleSettingChanged);
ThumbnailSize = InArgs._InitialThumbnailSize;
// Get desktop metrics
FDisplayMetrics DisplayMetrics;
FSlateApplication::Get().GetCachedDisplayMetrics( DisplayMetrics );
const FIntPoint DisplaySize(
DisplayMetrics.PrimaryDisplayWorkAreaRect.Right - DisplayMetrics.PrimaryDisplayWorkAreaRect.Left,
DisplayMetrics.PrimaryDisplayWorkAreaRect.Bottom - DisplayMetrics.PrimaryDisplayWorkAreaRect.Top );
ThumbnailScaleRangeScalar = (float)DisplaySize.Y / 2160.f;
// Use the shared ThumbnailPool for the rendering of thumbnails
AssetThumbnailPool = UThumbnailManager::Get().GetSharedThumbnailPool();
NumOffscreenThumbnails = 128;
ListViewThumbnailResolution = 128;
ListViewThumbnailSize = 32;
ListViewThumbnailPadding = 2;
TileViewThumbnailResolution = 256;
// Max Size for the thumbnail
#if UE_CONTENTBROWSER_NEW_STYLE
constexpr int32 MaxTileViewThumbnailSize = 160;
#else
constexpr int32 MaxTileViewThumbnailSize = 150;
#endif
TileViewThumbnailSize = MaxTileViewThumbnailSize;
TileViewThumbnailPadding = 9;
TileViewNameHeight = 50;
UpdateThumbnailSizeValue();
MinThumbnailScale = 0.1f * ThumbnailScaleRangeScalar;
MaxThumbnailScale = 1.9f * ThumbnailScaleRangeScalar;
bCanShowClasses = InArgs._CanShowClasses;
bCanShowFolders = InArgs._CanShowFolders;
bCanShowReadOnlyFolders = InArgs._CanShowReadOnlyFolders;
bFilterRecursivelyWithBackendFilter = InArgs._FilterRecursivelyWithBackendFilter;
bCanShowRealTimeThumbnails = InArgs._CanShowRealTimeThumbnails;
bCanShowDevelopersFolder = InArgs._CanShowDevelopersFolder;
bCanShowFavorites = InArgs._CanShowFavorites;
bCanDockCollections = InArgs._CanDockCollections;
SelectionMode = InArgs._SelectionMode;
bShowPathInColumnView = InArgs._ShowPathInColumnView;
bShowTypeInColumnView = InArgs._ShowTypeInColumnView;
bSortByPathInColumnView = bShowPathInColumnView && InArgs._SortByPathInColumnView;
bShowTypeInTileView = InArgs._ShowTypeInTileView;
bForceShowEngineContent = InArgs._ForceShowEngineContent;
bForceShowPluginContent = InArgs._ForceShowPluginContent;
bForceHideScrollbar = InArgs._ForceHideScrollbar;
bShowDisallowedAssetClassAsUnsupportedItems = InArgs._ShowDisallowedAssetClassAsUnsupportedItems;
bPendingUpdateThumbnails = false;
bShouldNotifyNextAssetSync = true;
CurrentThumbnailSize = TileViewThumbnailSize;
SourcesData = InArgs._InitialSourcesData;
BackendFilter = InArgs._InitialBackendFilter;
FrontendFilters = InArgs._FrontendFilters;
if (FrontendFilters.IsValid())
{
FrontendFilters->OnChanged().AddSP(this, &SAssetView::OnFrontendFiltersChanged);
}
TextFilter = InArgs._TextFilter;
if (TextFilter.IsValid())
{
TextFilter->OnChanged().AddSP(this, &SAssetView::OnFrontendFiltersChanged);
}
OnShouldFilterAsset = InArgs._OnShouldFilterAsset;
OnShouldFilterItem = InArgs._OnShouldFilterItem;
OnNewItemRequested = InArgs._OnNewItemRequested;
OnItemSelectionChanged = InArgs._OnItemSelectionChanged;
OnItemsActivated = InArgs._OnItemsActivated;
OnGetItemContextMenu = InArgs._OnGetItemContextMenu;
OnItemRenameCommitted = InArgs._OnItemRenameCommitted;
OnAssetTagWantsToBeDisplayed = InArgs._OnAssetTagWantsToBeDisplayed;
OnIsAssetValidForCustomToolTip = InArgs._OnIsAssetValidForCustomToolTip;
OnGetCustomAssetToolTip = InArgs._OnGetCustomAssetToolTip;
OnVisualizeAssetToolTip = InArgs._OnVisualizeAssetToolTip;
OnAssetToolTipClosing = InArgs._OnAssetToolTipClosing;
OnGetCustomSourceAssets = InArgs._OnGetCustomSourceAssets;
HighlightedText = InArgs._HighlightedText;
ThumbnailLabel = InArgs._ThumbnailLabel;
AllowThumbnailHintLabel = InArgs._AllowThumbnailHintLabel;
InitialCategoryFilter = InArgs._InitialCategoryFilter;
AssetShowWarningText = InArgs._AssetShowWarningText;
bAllowDragging = InArgs._AllowDragging;
bAllowFocusOnSync = InArgs._AllowFocusOnSync;
HiddenColumnNames = DefaultHiddenColumnNames = InArgs._HiddenColumnNames;
CustomColumns = InArgs._CustomColumns;
OnSearchOptionsChanged = InArgs._OnSearchOptionsChanged;
bShowPathViewFilters = InArgs._bShowPathViewFilters;
OnExtendAssetViewOptionsMenuContext = InArgs._OnExtendAssetViewOptionsMenuContext;
AssetViewOptionsProfile = InArgs._AssetViewOptionsProfile;
if ( InArgs._InitialViewType >= 0 && InArgs._InitialViewType < EAssetViewType::MAX )
{
CurrentViewType = InArgs._InitialViewType;
}
else
{
CurrentViewType = EAssetViewType::Tile;
}
bPendingSortFilteredItems = false;
bQuickFrontendListRefreshRequested = false;
bSlowFullListRefreshRequested = false;
LastSortTime = 0;
SortDelaySeconds = 8;
bBulkSelecting = false;
bAllowThumbnailEditMode = InArgs._AllowThumbnailEditMode;
bThumbnailEditMode = false;
bUserSearching = false;
bPendingFocusOnSync = false;
bWereItemsRecursivelyFiltered = false;
OwningContentBrowser = InArgs._OwningContentBrowser;
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
AssetClassPermissionList = AssetToolsModule.Get().GetAssetClassPathPermissionList(EAssetClassAction::ViewAsset);
FolderPermissionList = AssetToolsModule.Get().GetFolderPermissionList();
WritableFolderPermissionList = AssetToolsModule.Get().GetWritableFolderPermissionList();
if(InArgs._AllowCustomView)
{
FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
if(ContentBrowserModule.GetContentBrowserViewExtender().IsBound())
{
ViewExtender = ContentBrowserModule.GetContentBrowserViewExtender().Execute();
// Bind the delegates the custom view is responsible for firing
if(ViewExtender)
{
ViewExtender->OnSelectionChanged().BindSP(this, &SAssetView::AssetSelectionChanged);
ViewExtender->OnContextMenuOpened().BindSP(this, &SAssetView::OnGetContextMenuContent);
ViewExtender->OnItemScrolledIntoView().BindSP(this, &SAssetView::ItemScrolledIntoView);
ViewExtender->OnItemDoubleClicked().BindSP(this, &SAssetView::OnListMouseButtonDoubleClick);
}
}
}
FEditorWidgetsModule& EditorWidgetsModule = FModuleManager::LoadModuleChecked<FEditorWidgetsModule>("EditorWidgets");
TSharedRef<SWidget> AssetDiscoveryIndicator = EditorWidgetsModule.CreateAssetDiscoveryIndicator(EAssetDiscoveryIndicatorScaleMode::Scale_Vertical);
TSharedRef<SVerticalBox> VerticalBox = SNew(SVerticalBox);
BindCommands();
ChildSlot
.Padding(0.0f)
[
SNew(SBorder)
.Padding(0.f)
.BorderImage(FAppStyle::Get().GetBrush("Brushes.Panel"))
[
VerticalBox
]
];
// Assets area
VerticalBox->AddSlot()
.FillHeight(1.f)
[
SNew( SVerticalBox )
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew( SBox )
.Visibility_Lambda([this] { return InitialNumAmortizedTasks > 0 ? EVisibility::SelfHitTestInvisible : EVisibility::Collapsed; })
.HeightOverride( 2.f )
[
SNew( SProgressBar )
.Percent( this, &SAssetView::GetIsWorkingProgressBarState )
.BorderPadding( FVector2D(0,0) )
]
]
+ SVerticalBox::Slot()
.FillHeight(1.f)
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SAssignNew(ViewContainer, SBox)
.Padding(6.0f)
]
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Center)
.Padding(FMargin(0, 14, 0, 0))
[
// A warning to display when there are no assets to show
SNew( STextBlock )
.Justification( ETextJustify::Center )
.Text( this, &SAssetView::GetAssetShowWarningText )
.Visibility( this, &SAssetView::IsAssetShowWarningTextVisible )
.AutoWrapText( true )
]
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Bottom)
.Padding(FMargin(24, 0, 24, 0))
[
// Asset discovery indicator
AssetDiscoveryIndicator
]
+ SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Bottom)
.Padding(FMargin(8, 0))
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ErrorReporting.EmptyBox"))
.BorderBackgroundColor(this, &SAssetView::GetQuickJumpColor)
.Visibility(this, &SAssetView::IsQuickJumpVisible)
[
SNew(STextBlock)
.Text(this, &SAssetView::GetQuickJumpTerm)
]
]
]
];
// Thumbnail edit mode banner
VerticalBox->AddSlot()
.AutoHeight()
.Padding(0.f, 4.f)
[
SNew(SBorder)
.Visibility( this, &SAssetView::GetEditModeLabelVisibility )
.BorderImage(FAppStyle::Get().GetBrush("Brushes.Panel"))
.Content()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.VAlign(VAlign_Center)
.Padding(4.f, 0.f, 0.f, 0.f)
.FillWidth(1.f)
[
SNew(STextBlock)
.Text(LOCTEXT("ThumbnailEditModeLabel", "Editing Thumbnails. Drag a thumbnail to rotate it if there is a 3D environment."))
.ColorAndOpacity(FAppStyle::Get().GetSlateColor("Colors.Primary"))
]
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(SPrimaryButton)
.Text(LOCTEXT("EndThumbnailEditModeButton", "Done Editing"))
.OnClicked(this, &SAssetView::EndThumbnailEditModeClicked)
]
]
];
if (InArgs._ShowBottomToolbar)
{
// Bottom panel
VerticalBox->AddSlot()
.AutoHeight()
[
SNew(SHorizontalBox)
// Asset count
+SHorizontalBox::Slot()
.FillWidth(1.f)
.VAlign(VAlign_Center)
.Padding(8, 5)
[
SNew(STextBlock)
.Text(this, &SAssetView::GetAssetCountText)
]
// View mode combo button
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SComboButton)
.Visibility(InArgs._ShowViewOptions ? EVisibility::Visible : EVisibility::Collapsed)
.ContentPadding(0.f)
.ButtonStyle( FAppStyle::Get(), "ToggleButton" ) // Use the tool bar item style for this button
.OnGetMenuContent( this, &SAssetView::GetViewButtonContent )
.ButtonContent()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(SImage)
.Image( FAppStyle::GetBrush("GenericViewButton") )
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(2.f, 0.f, 0.f, 0.f)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text( LOCTEXT("ViewButton", "View Options") )
]
]
]
];
}
CreateCurrentView();
if( InArgs._InitialAssetSelection.IsValid() )
{
// sync to the initial item without notifying of selection
bShouldNotifyNextAssetSync = false;
SyncToLegacy( MakeArrayView(&InArgs._InitialAssetSelection, 1), TArrayView<const FString>() );
}
// If currently looking at column, and you could choose to sort by path in column first and then name
// Generalizing this is a bit difficult because the column ID is not accessible or is not known
// Currently I assume this won't work, if this view mode is not column. Otherwise, I don't think sorting by path
// is a good idea.
if (CurrentViewType == EAssetViewType::Column && bSortByPathInColumnView)
{
SortManager.SetSortColumnId(EColumnSortPriority::Primary, SortManager.PathColumnId);
SortManager.SetSortColumnId(EColumnSortPriority::Secondary, SortManager.NameColumnId);
SortManager.SetSortMode(EColumnSortPriority::Primary, EColumnSortMode::Ascending);
SortManager.SetSortMode(EColumnSortPriority::Secondary, EColumnSortMode::Ascending);
SortList();
}
})");
constexpr StrC SAssetView_GetThumbnailScale_Replacement = txt(R"(
float SAssetView::GetThumbnailScale() const
{
float BaseScale;
switch (ThumbnailSize)
{
case EThumbnailSize::Tiny:
BaseScale = 0.1f;
break;
case EThumbnailSize::Small:
BaseScale = 0.25f;
break;
case EThumbnailSize::Medium:
BaseScale = 0.40f;
break;
case EThumbnailSize::Large:
BaseScale = 0.60f;
break;
case EThumbnailSize::XLarge:
BaseScale = 0.8f;
break;
case EThumbnailSize::Huge:
BaseScale = 1.0f;
break;
default:
BaseScale = 0.5f;
break;
}
return BaseScale * GetTickSpaceGeometry().Scale;
})");
constexpr StrC SPropertyMenuAssetPicker_Construct_Replacement = txt(R"(
void SPropertyMenuAssetPicker::Construct( const FArguments& InArgs )
{
CurrentObject = InArgs._InitialObject;
PropertyHandle = InArgs._PropertyHandle;
const TArray<FAssetData>& OwnerAssetArray = InArgs._OwnerAssetArray;
bAllowClear = InArgs._AllowClear;
bAllowCopyPaste = InArgs._AllowCopyPaste;
AllowedClasses = InArgs._AllowedClasses;
DisallowedClasses = InArgs._DisallowedClasses;
NewAssetFactories = InArgs._NewAssetFactories;
OnShouldFilterAsset = InArgs._OnShouldFilterAsset;
OnSet = InArgs._OnSet;
OnClose = InArgs._OnClose;
const bool bForceShowEngineContent = PropertyHandle ? PropertyHandle->HasMetaData(TEXT("ForceShowEngineContent")) : false;
const bool bForceShowPluginContent = PropertyHandle ? PropertyHandle->HasMetaData(TEXT("ForceShowPluginContent")) : false;
const bool bInShouldCloseWindowAfterMenuSelection = true;
const bool bCloseSelfOnly = true;
const bool bSearchable = false;
FMenuBuilder MenuBuilder(bInShouldCloseWindowAfterMenuSelection, nullptr, nullptr, bCloseSelfOnly, &FCoreStyle::Get(), bSearchable);
if (NewAssetFactories.Num() > 0)
{
MenuBuilder.BeginSection(NAME_None, LOCTEXT("CreateNewAsset", "Create New Asset"));
{
for (UFactory* Factory : NewAssetFactories)
{
TWeakObjectPtr<UFactory> FactoryPtr(Factory);
MenuBuilder.AddMenuEntry(
Factory->GetDisplayName(),
Factory->GetToolTip(),
FSlateIconFinder::FindIconForClass(Factory->GetSupportedClass()),
FUIAction(FExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::OnCreateNewAssetSelected, FactoryPtr))
);
}
}
MenuBuilder.EndSection();
}
if (CurrentObject.IsValid() || bAllowCopyPaste || bAllowClear)
{
MenuBuilder.BeginSection(NAME_None, LOCTEXT("CurrentAssetOperationsHeader", "Current Asset"));
{
if (CurrentObject.IsValid())
{
MenuBuilder.AddMenuEntry(
LOCTEXT("EditAsset", "Edit"),
LOCTEXT("EditAsset_Tooltip", "Edit this asset"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),"Icons.Edit"),
FUIAction(FExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::OnEdit)));
}
if (bAllowCopyPaste)
{
MenuBuilder.AddMenuEntry(
LOCTEXT("CopyAsset", "Copy"),
LOCTEXT("CopyAsset_Tooltip", "Copies the asset to the clipboard"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),"GenericCommands.Copy"),
FUIAction(FExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::OnCopy))
);
MenuBuilder.AddMenuEntry(
LOCTEXT("PasteAsset", "Paste"),
LOCTEXT("PasteAsset_Tooltip", "Pastes an asset from the clipboard to this field"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),"GenericCommands.Paste"),
FUIAction(
FExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::OnPaste),
FCanExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::CanPaste))
);
}
if (bAllowClear)
{
MenuBuilder.AddMenuEntry(
LOCTEXT("ClearAsset", "Clear"),
LOCTEXT("ClearAsset_ToolTip", "Clears the asset set on this field"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),"GenericCommands.Delete"),
FUIAction(FExecuteAction::CreateSP(this, &SPropertyMenuAssetPicker::OnClear))
);
}
}
MenuBuilder.EndSection();
}
MenuBuilder.BeginSection(NAME_None, LOCTEXT("BrowseHeader", "Browse"));
{
FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
FAssetPickerConfig AssetPickerConfig;
// Add filter classes - if we have a single filter class of "Object" then don't set a filter since it would always match everything (but slower!)
if (AllowedClasses.Num() == 1 && AllowedClasses[0] == UObject::StaticClass())
{
AssetPickerConfig.Filter.ClassPaths.Reset();
}
else
{
for(int32 i = 0; i < AllowedClasses.Num(); ++i)
{
AssetPickerConfig.Filter.ClassPaths.Add( AllowedClasses[i]->GetClassPathName() );
}
}
for (int32 i = 0; i < DisallowedClasses.Num(); ++i)
{
AssetPickerConfig.Filter.RecursiveClassPathsExclusionSet.Add(DisallowedClasses[i]->GetClassPathName());
}
// Allow child classes
AssetPickerConfig.Filter.bRecursiveClasses = true;
// Set a delegate for setting the asset from the picker
AssetPickerConfig.OnAssetSelected = FOnAssetSelected::CreateSP(this, &SPropertyMenuAssetPicker::OnAssetSelected);
// Set a delegate for setting the asset from the picker via the keyboard
AssetPickerConfig.OnAssetEnterPressed = FOnAssetEnterPressed::CreateSP(this, &SPropertyMenuAssetPicker::OnAssetEnterPressed);
// Use the list view by default
AssetPickerConfig.InitialAssetViewType = EAssetViewType::List;
// The initial selection should be the current value
AssetPickerConfig.InitialAssetSelection = CurrentObject;
// We'll do clearing ourselves
AssetPickerConfig.bAllowNullSelection = false;
// Focus search box
AssetPickerConfig.bFocusSearchBoxWhenOpened = true;
// Apply custom filter
AssetPickerConfig.OnShouldFilterAsset = OnShouldFilterAsset;
// Don't allow dragging
AssetPickerConfig.bAllowDragging = false;
// Note(Ed): Personal changes
AssetPickerConfig.ThumbnailScale = 0.25;
AssetPickerConfig.InitialThumbnailSize = EThumbnailSize::Small;
// Save the settings into a special section for asset pickers for properties
AssetPickerConfig.SaveSettingsName = TEXT("AssetPropertyPicker");
// Populate the referencing assets via property handle
AssetPickerConfig.PropertyHandle = PropertyHandle;
// Populate the additional referencing assets with the Owner asset data
AssetPickerConfig.AdditionalReferencingAssets = OwnerAssetArray;
// Force show engine content if meta data says so
AssetPickerConfig.bForceShowEngineContent = bForceShowEngineContent;
// Force show plugin content if meta data says so
AssetPickerConfig.bForceShowPluginContent = bForceShowPluginContent;
AssetPickerWidget = ContentBrowserModule.Get().CreateAssetPicker(AssetPickerConfig);
TSharedRef<SWidget> MenuContent =
SNew(SBox)
.WidthOverride(static_cast<float>(PropertyEditorAssetConstants::ContentBrowserWindowSize.X))
.HeightOverride(static_cast<float>(PropertyEditorAssetConstants::ContentBrowserWindowSize.Y))
[
AssetPickerWidget.ToSharedRef()
];
MenuBuilder.AddWidget(MenuContent, FText::GetEmpty(), true);
}
MenuBuilder.EndSection();
ChildSlot
[
MenuBuilder.MakeWidget()
];
})");
void change_EditorContentList()
{
// Change property editor constant
{
#define path_PropertyEditorAssetConstantsHeader \
R"(C:\Projects\Unreal\Surgo\UE\Engine\Source\Editor\PropertyEditor\Private\UserInterface\PropertyEditor\PropertyEditorAssetConstants.h)"
FileContents content = file_read_contents( GlobalAllocator, true, path_PropertyEditorAssetConstantsHeader );
CodeBody parsed_PropertyEditorAssetConstantsHeader = parse_global_body( StrC { content.size, (char const*)content.data });
CodeBody changed_PropertyEditorAssetConstantsHeader = def_body(ECode::Global_Body);
for ( Code code : parsed_PropertyEditorAssetConstantsHeader )
{
switch ( code->Type )
{
using namespace ECode;
case Namespace:
CodeNS ns = code.cast<CodeNS>();
for ( Code ns_code : ns->Body )
{
switch ( ns_code->Type )
{
case Variable:
CodeVar var = ns_code.cast<CodeVar>();
if ( var->Name.starts_with(txt("ContentBrowserWindowSize")) )
{
// Swap value with new value
var->Value->Content = get_cached_string(txt("300.0f, 600.0f"));
Gasa::LogEditor("Swapped: " + to_fstring(var->Name));
}
break;
}
}
break;
}
changed_PropertyEditorAssetConstantsHeader.append( code );
}
Builder SBlueprintActionMenu_Changed = Builder::open(path_PropertyEditorAssetConstantsHeader);
SBlueprintActionMenu_Changed.print( def_comment(txt("This file was regenerated by GasaGen/ChangeEditorContentList.cpp")));
SBlueprintActionMenu_Changed.print(changed_PropertyEditorAssetConstantsHeader);
SBlueprintActionMenu_Changed.write();
format_file(path_PropertyEditorAssetConstantsHeader, false );
}
// Change SAssetView's Construct & GetThumbnailScale
{
#define path_SAssetView \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\ContentBrowser\Private\SAssetView.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SAssetView );
CodeBody parsed_SAssetViewCpp = parse_global_body( StrC { content.size, (char const*)content.data });
CodeFn signature_Construct = parse_function( code(
void SAssetView::Construct( const FArguments& InArgs ) {}
));
CodeFn signature_GetThumbnailScale = parse_function( code(
float SAssetView::GetThumbnailScale() const {}
));
CodeBody changed_SAssetViewCpp = def_body(ECode::Global_Body);
for ( Code code : parsed_SAssetViewCpp )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
{
CodeFn function_def = code.cast<CodeFn>();
if ( String::are_equal(function_def->Name, signature_Construct->Name)
&& function_def->Params.is_equal(signature_Construct->Params))
{
code = parse_function( SAssetView_Construct_Replacement );
Gasa::LogEditor("Swapped: " + to_fstring(function_def->Name));
}
else if ( String::are_equal(function_def->Name, signature_GetThumbnailScale->Name)
&& function_def->Params.is_equal(signature_GetThumbnailScale->Params))
{
code = parse_function( SAssetView_GetThumbnailScale_Replacement );
Gasa::LogEditor("Swapped: " + to_fstring(function_def->Name));
}
}
break;
}
changed_SAssetViewCpp.append( code );
}
Builder SBlueprintActionMenu_Changed = Builder::open(path_SAssetView);
SBlueprintActionMenu_Changed.print( def_comment(txt("This file was regenerated by GasaGen/ChangeEditorContentList.cpp")));
SBlueprintActionMenu_Changed.print(changed_SAssetViewCpp);
SBlueprintActionMenu_Changed.write();
format_file(path_SAssetView, false );
}
// Change SAssetView's Construct & GetThumbnailScale
{
#define path_SPropertyMenuAssetPicker \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\PropertyEditor\Private\UserInterface\PropertyEditor\SPropertyMenuAssetPicker.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SPropertyMenuAssetPicker );
CodeBody parsed = parse_global_body( StrC { content.size, (char const*)content.data });
CodeFn signature = parse_function( code(
void SPropertyMenuAssetPicker::Construct( const FArguments& InArgs ) {}
));
CodeBody changed = def_body(ECode::Global_Body);
for ( Code code : parsed )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
{
CodeFn function_def = code.cast<CodeFn>();
if ( String::are_equal(function_def->Name, signature->Name)
&& function_def->Params.is_equal(signature->Params))
{
code = parse_function( SPropertyMenuAssetPicker_Construct_Replacement );
Gasa::LogEditor("Swapped: " + to_fstring(function_def->Name));
}
}
break;
}
changed.append( code );
}
Builder SBlueprintActionMenu_Changed = Builder::open(path_SPropertyMenuAssetPicker);
SBlueprintActionMenu_Changed.print( def_comment(txt("This file was regenerated by GasaGen/ChangeEditorContentList.cpp")));
SBlueprintActionMenu_Changed.print(changed);
SBlueprintActionMenu_Changed.write();
format_file(path_SPropertyMenuAssetPicker, false );
}
}

View File

@ -0,0 +1,3 @@
#pragma once
void change_EditorContentList();

View File

@ -1,4 +1,4 @@
#include "GasaGen_DevOptionsCache.h" #include "DevOptionsCache.h"
#include "GasaGen_Common.h" #include "GasaGen_Common.h"
#pragma push_macro("GASA_API") #pragma push_macro("GASA_API")

View File

@ -1,9 +1,11 @@
#include "GasaGen.h" #include "GasaGen.h"
#include "GasaGen_Common.h" #include "GasaGen_Common.h"
#include "GasaGen_AttributeSets.h" #include "AttributeSets.h"
#include "GasaGen_DevOptionsCache.h" #include "ChangeBPActionMenu.h"
#include "DevOptionsCache.h"
// Editor Module // Editor Module
#include "ChangeEditorContentList.h"
#include "GasaEditorCommon.h" #include "GasaEditorCommon.h"
#define LOCTEXT_NAMESPACE "GasaEditor" #define LOCTEXT_NAMESPACE "GasaEditor"
@ -51,11 +53,11 @@ void Execute_GasaModule_Codegen()
#undef USTRUCT #undef USTRUCT
#undef GENERATED_BODY #undef GENERATED_BODY
#undef GASA_API #undef GASA_API
UHT_UCLASS = code_str(UCLASS()); UHT_UCLASS = code_str(UCLASS());
UHT_UPROPERTY = code_str(UPROPERTY()); UHT_UPROPERTY = code_str(UPROPERTY());
UHT_USTRUCT = code_str(USTRUCT()); UHT_USTRUCT = code_str(USTRUCT());
UHT_GENERATED_BODY = code_str(GENERATED_BODY()\n); UHT_GENERATED_BODY = code_str(GENERATED_BODY()\n);
UModule_GASA_API = code_str(GASA_API); UModule_GASA_API = code_str(GASA_API);
#pragma pop_macro("UCLASS") #pragma pop_macro("UCLASS")
#pragma pop_macro("UPROPERTY") #pragma pop_macro("UPROPERTY")
#pragma pop_macro("USTRUCT") #pragma pop_macro("USTRUCT")
@ -111,9 +113,11 @@ void Execute_GasaModule_Codegen()
PreprocessorDefines.append(get_cached_string(str_UE_REQUIRES)); PreprocessorDefines.append(get_cached_string(str_UE_REQUIRES));
} }
generate_AttributeSets(); // generate_AttributeSets();
//generate_DevOptionsCache(); //generate_DevOptionsCache();
//generate_HostWidgetController(); //generate_HostWidgetController();
change_SBlueprintActionMenu_Construct();
change_EditorContentList();
gen::deinit(); gen::deinit();
}); });

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
UE_DISABLE_OPTIMIZATION
#include "gencpp/gen.hpp" #include "gencpp/gen.hpp"
#include "gencpp/gen.builder.hpp" #include "gencpp/gen.builder.hpp"
UE_ENABLE_OPTIMIZATION
using namespace gen; using namespace gen;
// Codegen assumes its working directory is the project // Codegen assumes its working directory is the project
@ -97,10 +98,12 @@ Builder builder_open(char const* path) {
// CodeConstructor find_constructor( StrC parent_name, ) // CodeConstructor find_constructor( StrC parent_name, )
inline inline
void format_file( char const* path ) void format_file( char const* path, bool relative_path = true )
{ {
String String
resolved_path = String::make(GlobalAllocator, StrC(Project_Path)); resolved_path = String::make_reserve(GlobalAllocator, Project_Path.length());
if (relative_path)
resolved_path.append(StrC(Project_Path));
resolved_path.append(path); resolved_path.append(path);
String style_arg = String::make(GlobalAllocator, txt("-style=file:")); String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
@ -136,3 +139,9 @@ String to_string( FName ue_fname ) {
char const* ansi_str = TCHAR_TO_ANSI(*ue_fname.ToString()); char const* ansi_str = TCHAR_TO_ANSI(*ue_fname.ToString());
return String::make_length(GlobalAllocator, ansi_str, ue_fname.GetStringLength()); return String::make_length(GlobalAllocator, ansi_str, ue_fname.GetStringLength());
} }
FORCEINLINE
FString to_fstring( String string )
{
return FString::ConstructFromPtrSize( string.Data, string.length() );
}

View File

@ -24,7 +24,6 @@
#include "gen.hpp" #include "gen.hpp"
GEN_NS_BEGIN GEN_NS_BEGIN
#pragma region StaticData #pragma region StaticData
// TODO : Convert global allocation strategy to use a slab allocation strategy. // TODO : Convert global allocation strategy to use a slab allocation strategy.
@ -2728,11 +2727,19 @@ void CodeVar::to_string( String& result )
} }
if ( ast->Value ) if ( ast->Value )
result.append_fmt( " = %S", ast->Value.to_string() ); {
if ( ast->VarConstructorInit )
result.append_fmt( "( %S ", ast->Value.to_string() );
else
result.append_fmt( " = %S", ast->Value.to_string() );
}
// Keep the chain going... // Keep the chain going...
if ( ast->NextVar ) if ( ast->NextVar )
result.append_fmt( ", %S", ast->NextVar.to_string() ); result.append_fmt( ", %S", ast->NextVar.to_string() );
if ( ast->VarConstructorInit )
result.append( " )");
return; return;
} }
@ -2766,11 +2773,19 @@ void CodeVar::to_string( String& result )
result.append_fmt( " : %S", ast->BitfieldSize.to_string() ); result.append_fmt( " : %S", ast->BitfieldSize.to_string() );
if ( ast->Value ) if ( ast->Value )
result.append_fmt( " = %S", ast->Value.to_string() ); {
if ( ast->VarConstructorInit )
result.append_fmt( "( %S", ast->Value.to_string() );
else
result.append_fmt( " = %S", ast->Value.to_string() );
}
if ( ast->NextVar ) if ( ast->NextVar )
result.append_fmt( ", %S", ast->NextVar.to_string() ); result.append_fmt( ", %S", ast->NextVar.to_string() );
if ( ast->VarConstructorInit )
result.append( " )" );
if ( ast->InlineCmt ) if ( ast->InlineCmt )
result.append_fmt( "; %S", ast->InlineCmt->Content ); result.append_fmt( "; %S", ast->InlineCmt->Content );
else else
@ -2798,11 +2813,19 @@ void CodeVar::to_string( String& result )
result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name );
if ( ast->Value ) if ( ast->Value )
result.append_fmt( " = %S", ast->Value.to_string() ); {
if ( ast->VarConstructorInit )
result.append_fmt( "( %S ", ast->Value.to_string() );
else
result.append_fmt( " = %S", ast->Value.to_string() );
}
if ( ast->NextVar ) if ( ast->NextVar )
result.append_fmt( ", %S", ast->NextVar.to_string() ); result.append_fmt( ", %S", ast->NextVar.to_string() );
if ( ast->VarConstructorInit )
result.append(")");
result.append( ";" ); result.append( ";" );
if ( ast->InlineCmt ) if ( ast->InlineCmt )
@ -2993,16 +3016,17 @@ internal void define_constants()
spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \ spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \
spec_##Type_.set_global(); spec_##Type_.set_global();
#pragma push_macro( "FORCEINLINE" ) #pragma push_macro("FORCEINLINE")
#pragma push_macro( "global" ) #pragma push_macro("global")
#pragma push_macro( "internal" ) #pragma push_macro("internal")
#pragma push_macro( "local_persist" ) #pragma push_macro("local_persist")
#pragma push_macro( "neverinline" ) #pragma push_macro("neverinline")
#undef FORCEINLINE #undef FORCEINLINE
#undef global #undef global
#undef internal #undef internal
#undef local_persist #undef local_persist
#undef neverinline #undef neverinline
def_constant_spec( const, ESpecifier::Const ); def_constant_spec( const, ESpecifier::Const );
def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( consteval, ESpecifier::Consteval );
def_constant_spec( constexpr, ESpecifier::Constexpr ); def_constant_spec( constexpr, ESpecifier::Constexpr );
@ -3027,14 +3051,14 @@ internal void define_constants()
def_constant_spec( virtual, ESpecifier::Virtual ); def_constant_spec( virtual, ESpecifier::Virtual );
def_constant_spec( volatile, ESpecifier::Volatile ) def_constant_spec( volatile, ESpecifier::Volatile )
spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist );
spec_local_persist.set_global(); spec_local_persist.set_global();
#pragma pop_macro( "FORCEINLINE" ) #pragma pop_macro("FORCEINLINE")
#pragma pop_macro( "global" ) #pragma pop_macro("global")
#pragma pop_macro( "internal" ) #pragma pop_macro("internal")
#pragma pop_macro( "local_persist" ) #pragma pop_macro("local_persist")
#pragma pop_macro( "neverinline" ) #pragma pop_macro("neverinline")
#undef def_constant_spec #undef def_constant_spec
} }
@ -7096,6 +7120,26 @@ namespace parser
move_forward(); move_forward();
token.Length++; token.Length++;
} }
// Handle number literal suffixes in a botched way
if (left && (
current == 'l' || current == 'L' || // long/long long
current == 'u' || current == 'U' || // unsigned
current == 'f' || current == 'F' || // float
current == 'i' || current == 'I' || // imaginary
current == 'z' || current == 'Z')) // complex
{
char prev = current;
move_forward();
token.Length++;
// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
if (left && (prev == 'l' || prev == 'L') && (current == 'l' || current == 'L'))
{
move_forward();
token.Length++;
}
}
} }
goto FoundToken; goto FoundToken;
@ -9563,6 +9607,7 @@ namespace parser
return result; return result;
} }
__pragma(optimize("",off))
internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ) internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers )
{ {
push_scope(); push_scope();
@ -9623,7 +9668,14 @@ namespace parser
Token name = parse_identifier(); Token name = parse_identifier();
Context.Scope->Name = name; Context.Scope->Name = name;
if ( check( TokType::Capture_Start ) ) bool detected_capture = check( TokType::Capture_Start );
// Check three tokens ahead to make sure that were not dealing with a constructor initialization...
// ( 350.0f , <--- Could be the scenario
// Example : <Capture_Start> <Value> <Comma>
// idx +1 +2
bool detected_comma = Context.Tokens.Arr[ Context.Tokens.Idx + 2 ].Type == TokType::Comma;
if ( detected_capture && ! detected_comma )
{ {
// Dealing with a function // Dealing with a function
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name ); result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
@ -9647,6 +9699,7 @@ namespace parser
Context.pop(); Context.pop();
return result; return result;
} }
__pragma(optimize("",on))
internal CodePragma parse_pragma() internal CodePragma parse_pragma()
{ {
@ -10150,6 +10203,8 @@ namespace parser
Code expr = { nullptr }; Code expr = { nullptr };
Code bitfield_expr = { nullptr }; Code bitfield_expr = { nullptr };
b32 using_constructor_initializer = false;
if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) )
{ {
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression> // <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
@ -10180,6 +10235,33 @@ namespace parser
expr = untyped_str( expr_tok ); expr = untyped_str( expr_tok );
// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> } // <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
} }
if ( currtok.Type == TokType::Capture_Start )
{
eat( TokType:: Capture_Start);
// <Attributes> <Specifiers> <ValueType> <Name> (
Token expr_token = currtok;
using_constructor_initializer = true;
s32 level = 0;
while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) )
{
if ( currtok.Type == TokType::Capture_Start )
level++;
else if ( currtok.Type == TokType::Capture_End && level > 0 )
level--;
eat( currtok.Type );
}
expr_token.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)expr_token.Text;
expr = untyped_str( expr_token );
eat( TokType::Capture_End );
// <Attributes> <Specifiers> <ValueType> <Name> ( <Expression> )
}
if ( currtok.Type == TokType::Assign_Classifer ) if ( currtok.Type == TokType::Assign_Classifer )
{ {
@ -10274,6 +10356,8 @@ namespace parser
result->NextVar->Parent = result; result->NextVar->Parent = result;
} }
result->VarConstructorInit = using_constructor_initializer;
Context.pop(); Context.pop();
return result; return result;
} }

View File

@ -886,6 +886,7 @@ struct AST
OperatorT Op; OperatorT Op;
AccessSpec ParentAccess; AccessSpec ParentAccess;
s32 NumEntries; s32 NumEntries;
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
}; };
}; };
@ -968,6 +969,7 @@ struct AST_POD
OperatorT Op; OperatorT Op;
AccessSpec ParentAccess; AccessSpec ParentAccess;
s32 NumEntries; s32 NumEntries;
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
}; };
}; };
@ -3174,7 +3176,7 @@ struct AST_Var
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
char _PAD_UNUSED_[sizeof( u32 )]; s32 VarConstructorInit;
}; };
static_assert( sizeof( AST_Var ) == sizeof( AST ), "ERROR: AST_Var is not the same size as AST" ); static_assert( sizeof( AST_Var ) == sizeof( AST ), "ERROR: AST_Var is not the same size as AST" );