// Copyright Epic Games, Inc. All Rights Reserved. #include "SPackageTableTreeView.h" #include "Framework/MultiBox/MultiBoxBuilder.h" #include "SlateOptMacros.h" #include "Widgets/Input/STextComboBox.h" // TraceServices #include "Common/ProviderLock.h" // TraceInsightsCore #include "InsightsCore/Table/ViewModels/TableColumn.h" #include "InsightsCore/Table/ViewModels/TreeNodeGrouping.h" // TraceInsights #include "Insights/InsightsStyle.h" #include "Insights/CookProfiler/CookProfilerManager.h" #include "Insights/CookProfiler/ViewModels/PackageEntry.h" #include "Insights/CookProfiler/ViewModels/PackageNode.h" #include "Insights/TimingProfiler/TimingProfilerManager.h" #include "Insights/TimingProfiler/Widgets/STimingProfilerWindow.h" #include "Insights/Widgets/STimingView.h" #include #define LOCTEXT_NAMESPACE "UE::Insights::CookProfiler::SPackageTableTreeView" namespace UE::Insights::CookProfiler { //////////////////////////////////////////////////////////////////////////////////////////////////// // FPackageTableTreeViewCommands //////////////////////////////////////////////////////////////////////////////////////////////////// class FPackageTableTreeViewCommands : public TCommands { public: FPackageTableTreeViewCommands() : TCommands( TEXT("PackageTableTreeViewCommands"), NSLOCTEXT("Contexts", "PackageTableTreeViewCommands", "Insights - Package Table Tree View"), NAME_None, FInsightsStyle::GetStyleSetName()) { } virtual ~FPackageTableTreeViewCommands() { } virtual void RegisterCommands() override { } }; //////////////////////////////////////////////////////////////////////////////////////////////////// // SPackageTableTreeView //////////////////////////////////////////////////////////////////////////////////////////////////// SPackageTableTreeView::SPackageTableTreeView() { bRunInAsyncMode = true; } //////////////////////////////////////////////////////////////////////////////////////////////////// SPackageTableTreeView::~SPackageTableTreeView() { } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::Construct(const FArguments& InArgs, TSharedPtr InTablePtr) { ConstructWidget(InTablePtr); AddCommmands(); ViewPreset_OnSelectionChanged(AvailableViewPresets[0], ESelectInfo::Direct); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::ExtendMenu(FMenuBuilder& MenuBuilder) { } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::AddCommmands() { FPackageTableTreeViewCommands::Register(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::Reset() { STableTreeView::Reset(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) { STableTreeView::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); if (!bIsUpdateRunning) { RebuildTree(false); } } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::RebuildTree(bool bResync) { if (bDataLoaded == true) { return; } TraceServices::FAnalysisSessionReadScope SessionReadScope(*Session.Get()); if (!Session->IsAnalysisComplete()) { return; } TSharedPtr PackageTable = GetPackageTable(); TArray& Packages = PackageTable->GetPackageEntries(); Packages.Empty(); TableRowNodes.Empty(); const TraceServices::ICookProfilerProvider* CookProvider = TraceServices::ReadCookProfilerProvider(*Session.Get()); if (CookProvider) { TraceServices::FProviderReadScopeLock ProviderReadScope(*CookProvider); TArray64 PackageAggregation; CookProvider->CreateAggregation(PackageAggregation); const uint32 NumPackages = CookProvider->GetNumPackages(); Packages.Reserve(NumPackages); TableRowNodes.Reserve(NumPackages); TArray* Nodes = &TableRowNodes; for (const TraceServices::FPackageData& Package : PackageAggregation) { Packages.Emplace(Package); uint32 Index = static_cast(Packages.Num() - 1); FName NodeName(Package.Name); FPackageNodePtr NodePtr = MakeShared(NodeName, PackageTable, Index); Nodes->Add(NodePtr); }; } bDataLoaded = true; UpdateTree(); TreeView->RebuildList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool SPackageTableTreeView::IsRunning() const { return STableTreeView::IsRunning(); } //////////////////////////////////////////////////////////////////////////////////////////////////// double SPackageTableTreeView::GetAllOperationsDuration() { return STableTreeView::GetAllOperationsDuration(); } //////////////////////////////////////////////////////////////////////////////////////////////////// FText SPackageTableTreeView::GetCurrentOperationName() const { return STableTreeView::GetCurrentOperationName(); } //////////////////////////////////////////////////////////////////////////////////////////////////// BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION TSharedPtr SPackageTableTreeView::ConstructToolbar() { TSharedPtr Box = SNew(SHorizontalBox); ConstructViewPreset(Box, 128.0f); return Box; } END_SLATE_FUNCTION_BUILD_OPTIMIZATION //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::InternalCreateGroupings() { STableTreeView::InternalCreateGroupings(); AvailableGroupings.RemoveAll( [](TSharedPtr& Grouping) { if (Grouping->Is()) { const FName ColumnId = Grouping->As().GetColumnId(); if (ColumnId == FPackageTableColumns::BeginCacheForCookedPlatformDataTimeInclColumnId || ColumnId == FPackageTableColumns::BeginCacheForCookedPlatformDataTimeExclColumnId || ColumnId == FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedInclColumnId || ColumnId == FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedExclColumnId || ColumnId == FPackageTableColumns::SaveTimeInclColumnId || ColumnId == FPackageTableColumns::SaveTimeExclColumnId || ColumnId == FPackageTableColumns::IdColumnId || ColumnId == FPackageTableColumns::NameColumnId || ColumnId == FPackageTableColumns::LoadTimeInclColumnId || ColumnId == FPackageTableColumns::LoadTimeExclColumnId) { return true; } } else if (Grouping->Is()) { const FName ColumnId = Grouping->As().GetColumnId(); if (ColumnId == FPackageTableColumns::PackageAssetClassColumnId) { return true; } } return false; }); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::TreeView_OnMouseButtonDoubleClick(FTableTreeNodePtr TreeNode) { STableTreeView::TreeView_OnMouseButtonDoubleClick(TreeNode); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::InitAvailableViewPresets() { ////////////////////////////////////////////////// // Default View class FDefaultViewPreset : public ITableTreeViewPreset { public: virtual FText GetName() const override { return LOCTEXT("Default_PresetName", "Default"); } virtual FText GetToolTip() const override { return LOCTEXT("Default_PresetToolTip", "Default View\nConfigure the tree view to show default packages info."); } virtual FName GetSortColumn() const override { return FTable::GetHierarchyColumnId(); } virtual EColumnSortMode::Type GetSortMode() const override { return EColumnSortMode::Type::Ascending; } virtual void SetCurrentGroupings(const TArray>& InAvailableGroupings, TArray>& InOutCurrentGroupings) const override { InOutCurrentGroupings.Reset(); check(InAvailableGroupings[0]->Is()); InOutCurrentGroupings.Add(InAvailableGroupings[0]); } virtual void GetColumnConfigSet(TArray& InOutConfigSet) const override { InOutConfigSet.Add({ FTable::GetHierarchyColumnId(), true, 500.0f }); InOutConfigSet.Add({ FPackageTableColumns::IdColumnId, true, 80.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::PackageAssetClassColumnId, true, 200.0f }); InOutConfigSet.Add({ FPackageTableColumns::NameColumnId, false, 400.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedInclColumnId, true, 100.0f }); } }; AvailableViewPresets.Add(MakeShared()); ////////////////////////////////////////////////// // Package Path Breakdown class FPackagePathViewPreset : public ITableTreeViewPreset { public: virtual FText GetName() const override { return LOCTEXT("PackagePath_PresetName", "Package Path"); } virtual FText GetToolTip() const override { return LOCTEXT("PackagePath_PresetToolTip", "Configure the tree view to show the packages grouped by package path."); } virtual FName GetSortColumn() const override { return FTable::GetHierarchyColumnId(); } virtual EColumnSortMode::Type GetSortMode() const override { return EColumnSortMode::Type::Ascending; } virtual void SetCurrentGroupings(const TArray>& InAvailableGroupings, TArray>& InOutCurrentGroupings) const override { InOutCurrentGroupings.Reset(); check(InAvailableGroupings[0]->Is()); InOutCurrentGroupings.Add(InAvailableGroupings[0]); const TSharedPtr* PackagePathGrouping = InAvailableGroupings.FindByPredicate( [](TSharedPtr& Grouping) { return Grouping->Is() && Grouping->As().GetColumnId() == FPackageTableColumns::NameColumnId; }); if (PackagePathGrouping) { InOutCurrentGroupings.Add(*PackagePathGrouping); } } virtual void GetColumnConfigSet(TArray& InOutConfigSet) const override { InOutConfigSet.Add({ FTable::GetHierarchyColumnId(), true, 500.0f }); InOutConfigSet.Add({ FPackageTableColumns::IdColumnId, true, 80.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::PackageAssetClassColumnId, true, 200.0f }); InOutConfigSet.Add({ FPackageTableColumns::NameColumnId, false, 400.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedInclColumnId, true, 100.0f }); } }; AvailableViewPresets.Add(MakeShared()); ////////////////////////////////////////////////// // Asset Class Breakdown class FAssetClassViewPreset : public ITableTreeViewPreset { public: virtual FText GetName() const override { return LOCTEXT("AssetClass_PresetName", "Asset Class"); } virtual FText GetToolTip() const override { return LOCTEXT("AssetClass_PresetToolTip", "Configure the tree view to show the packages grouped by their most important asset class."); } virtual FName GetSortColumn() const override { return FTable::GetHierarchyColumnId(); } virtual EColumnSortMode::Type GetSortMode() const override { return EColumnSortMode::Type::Ascending; } virtual void SetCurrentGroupings(const TArray>& InAvailableGroupings, TArray>& InOutCurrentGroupings) const override { InOutCurrentGroupings.Reset(); check(InAvailableGroupings[0]->Is()); InOutCurrentGroupings.Add(InAvailableGroupings[0]); const TSharedPtr* PackagePathGrouping = InAvailableGroupings.FindByPredicate( [](TSharedPtr& Grouping) { return Grouping->Is() && Grouping->As().GetColumnId() == FPackageTableColumns::PackageAssetClassColumnId; }); if (PackagePathGrouping) { InOutCurrentGroupings.Add(*PackagePathGrouping); } } virtual void GetColumnConfigSet(TArray& InOutConfigSet) const override { InOutConfigSet.Add({ FTable::GetHierarchyColumnId(), true, 300.0f }); InOutConfigSet.Add({ FPackageTableColumns::IdColumnId, true, 80.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedExclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::NameColumnId, true, 400.0f }); InOutConfigSet.Add({ FPackageTableColumns::PackageAssetClassColumnId, false, 200.0f }); InOutConfigSet.Add({ FPackageTableColumns::LoadTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::SaveTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::BeginCacheForCookedPlatformDataTimeInclColumnId, true, 100.0f }); InOutConfigSet.Add({ FPackageTableColumns::GetIsCachedCookedPlatformDataLoadedInclColumnId, true, 100.0f }); } }; AvailableViewPresets.Add(MakeShared()); SelectedViewPreset = AvailableViewPresets[0]; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SPackageTableTreeView::UpdateBannerText() { if (!bDataLoaded) { TreeViewBannerText = LOCTEXT("DataWillLoad", "Package data will load when session analysis is complete."); } else { STableTreeView::UpdateBannerText(); } } //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace UE::Insights::CookProfiler #undef LOCTEXT_NAMESPACE