// Copyright Epic Games, Inc. All Rights Reserved. #include "TimersViewColumnFactory.h" // Insights #include "Insights/Common/TimeUtils.h" #include "Insights/Table/ViewModels/TableCellValueFormatter.h" #include "Insights/Table/ViewModels/TableCellValueGetter.h" #include "Insights/Table/ViewModels/TableCellValueSorter.h" #include "Insights/ViewModels/TimerGroupingAndSorting.h" #include "Insights/ViewModels/TimerNodeHelper.h" #define LOCTEXT_NAMESPACE "STimerView" //////////////////////////////////////////////////////////////////////////////////////////////////// // Column identifiers const FName FTimersViewColumns::NameColumnID(TEXT("Name")); // TEXT("_Hierarchy") const FName FTimersViewColumns::MetaGroupNameColumnID(TEXT("MetaGroupName")); const FName FTimersViewColumns::TypeColumnID(TEXT("Type")); const FName FTimersViewColumns::InstanceCountColumnID(TEXT("Count")); // Inclusive Time columns const FName FTimersViewColumns::TotalInclusiveTimeColumnID(TEXT("TotalInclTime")); const FName FTimersViewColumns::MaxInclusiveTimeColumnID(TEXT("MaxInclTime")); const FName FTimersViewColumns::UpperQuartileInclusiveTimeColumnID(TEXT("UpperQuartileInclTime")); const FName FTimersViewColumns::AverageInclusiveTimeColumnID(TEXT("AverageInclTime")); const FName FTimersViewColumns::MedianInclusiveTimeColumnID(TEXT("MedianInclTime")); const FName FTimersViewColumns::LowerQuartileInclusiveTimeColumnID(TEXT("LowerQuartileInclTime")); const FName FTimersViewColumns::MinInclusiveTimeColumnID(TEXT("MinInclTime")); // Exclusive Time columns const FName FTimersViewColumns::TotalExclusiveTimeColumnID(TEXT("TotalExclTime")); const FName FTimersViewColumns::MaxExclusiveTimeColumnID(TEXT("MaxExclTime")); const FName FTimersViewColumns::UpperQuartileExclusiveTimeColumnID(TEXT("UpperQuartileExclTime")); const FName FTimersViewColumns::AverageExclusiveTimeColumnID(TEXT("AverageExclTime")); const FName FTimersViewColumns::MedianExclusiveTimeColumnID(TEXT("MedianExclTime")); const FName FTimersViewColumns::LowerQuartileExclusiveTimeColumnID(TEXT("LowerQuartileExclTime")); const FName FTimersViewColumns::MinExclusiveTimeColumnID(TEXT("MinExclTime")); //////////////////////////////////////////////////////////////////////////////////////////////////// void FTimersViewColumnFactory::CreateTimersViewColumns(TArray>& Columns) { Columns.Reset(); Columns.Add(CreateNameColumn()); Columns.Add(CreateMetaGroupNameColumn()); Columns.Add(CreateTypeColumn()); Columns.Add(CreateInstanceCountColumn()); Columns.Add(CreateTotalInclusiveTimeColumn()); Columns.Add(CreateMaxInclusiveTimeColumn()); Columns.Add(CreateAverageInclusiveTimeColumn()); Columns.Add(CreateMedianInclusiveTimeColumn()); Columns.Add(CreateMinInclusiveTimeColumn()); Columns.Add(CreateTotalExclusiveTimeColumn()); Columns.Add(CreateMaxExclusiveTimeColumn()); Columns.Add(CreateAverageExclusiveTimeColumn()); Columns.Add(CreateMedianExclusiveTimeColumn()); Columns.Add(CreateMinExclusiveTimeColumn()); } //////////////////////////////////////////////////////////////////////////////////////////////////// void FTimersViewColumnFactory::CreateTimerTreeViewColumns(TArray>& Columns) { Columns.Reset(); Columns.Add(CreateNameColumn()); Columns.Add(CreateTypeColumn()); Columns.Add(CreateInstanceCountColumn()); Columns.Add(CreateTotalInclusiveTimeColumn()); Columns.Add(CreateTotalExclusiveTimeColumn()); } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateNameColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::NameColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Name_ColumnName", "Name")); Column.SetTitleName(LOCTEXT("Name_ColumnTitle", "Timer or Group Name")); Column.SetDescription(LOCTEXT("Name_ColumnDesc", "Name of timer or group")); Column.SetFlags(ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered | ETableColumnFlags::IsHierarchy); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(246.0f); Column.SetMinWidth(42.0f); Column.SetDataType(ETableCellDataType::Text); TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMetaGroupNameColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MetaGroupNameColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MetaGroupName_ColumnName", "Meta Group")); Column.SetTitleName(LOCTEXT("MetaGroupName_ColumnTitle", "Meta Group Name")); Column.SetDescription(LOCTEXT("MetaGroupName_ColumnDesc", "Name of the meta group")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(100.0f); Column.SetDataType(ETableCellDataType::Text); class FMetaGroupNameValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MetaGroupNameColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(FText::FromName(TimerNode.GetMetaGroupName()))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateTypeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::TypeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Type_ColumnName", "Type")); Column.SetTitleName(LOCTEXT("Type_ColumnTitle", "Type")); Column.SetDescription(LOCTEXT("Type_ColumnDesc", "Type of timer or group")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(60.0f); Column.SetDataType(ETableCellDataType::Text); class FTimerTypeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::TypeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNodeTypeHelper::ToText(TimerNode.GetType()))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateInstanceCountColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::InstanceCountColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("InstanceCount_ColumnName", "Count")); Column.SetTitleName(LOCTEXT("InstanceCount_ColumnTitle", "Instance Count")); Column.SetDescription(LOCTEXT("InstanceCount_ColumnDesc", "Number of selected timer's instances")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(60.0f); Column.SetDataType(ETableCellDataType::Int64); class FInstanceCountValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::InstanceCountColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(static_cast(TimerNode.GetAggregatedStats().InstanceCount))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// // Inclusive Time Columns //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateTotalInclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::TotalInclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("TotalInclusiveTime_ColumnName", "Incl")); Column.SetTitleName(LOCTEXT("TotalInclusiveTime_ColumnTitle", "Total Inclusive Time")); Column.SetDescription(LOCTEXT("TotalInclusiveTime_ColumnDesc", "Total inclusive duration of selected timer's instances")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TotalTimeColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); Column.SetAggregation(ETableColumnAggregation::Sum); class FTotalInclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::TotalInclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().TotalInclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMaxInclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MaxInclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MaxInclusiveTime_ColumnName", "I.Max")); Column.SetTitleName(LOCTEXT("MaxInclusiveTime_ColumnTitle", "Max Inclusive Time (ms)")); Column.SetDescription(LOCTEXT("MaxInclusiveTime_ColumnDesc", "Maximum inclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMaxInclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MaxInclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MaxInclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateAverageInclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::AverageInclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("AvgInclusiveTime_ColumnName", "I.Avg")); Column.SetTitleName(LOCTEXT("AvgInclusiveTime_ColumnTitle", "Average Inclusive Time (ms)")); Column.SetDescription(LOCTEXT("AvgInclusiveTime_ColumnDesc", "Average inclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FAverageInclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::AverageInclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().AverageInclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMedianInclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MedianInclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MedInclusiveTime_ColumnName", "I.Med")); Column.SetTitleName(LOCTEXT("MedInclusiveTime_ColumnTitle", "Median Inclusive Time (ms)")); Column.SetDescription(LOCTEXT("MedInclusiveTime_ColumnDesc", "Median inclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMedianInclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MedianInclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MedianInclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMinInclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MinInclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MinInclusiveTime_ColumnName", "I.Min")); Column.SetTitleName(LOCTEXT("MinInclusiveTime_ColumnTitle", "Min Inclusive Time (ms)")); Column.SetDescription(LOCTEXT("MinInclusiveTime_ColumnDesc", "Minimum inclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMinInclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MinInclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MinInclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// // Exclusive Time Columns //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateTotalExclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::TotalExclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("TotalExclusiveTime_ColumnName", "Excl")); Column.SetTitleName(LOCTEXT("TotalExclusiveTime_ColumnTitle", "Total Exclusive Time")); Column.SetDescription(LOCTEXT("TotalExclusiveTime_ColumnDesc", "Total exclusive duration of selected timer's instances")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TotalTimeColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); Column.SetAggregation(ETableColumnAggregation::Sum); class FTotalExclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::TotalExclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().TotalExclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMaxExclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MaxExclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MaxExclusiveTime_ColumnName", "E.Max")); Column.SetTitleName(LOCTEXT("MaxExclusiveTime_ColumnTitle", "Max Exclusive Time (ms)")); Column.SetDescription(LOCTEXT("MaxExclusiveTime_ColumnDesc", "Maximum exclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMaxExclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MaxExclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MaxExclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateAverageExclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::AverageExclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("AvgExclusiveTime_ColumnName", "E.Avg")); Column.SetTitleName(LOCTEXT("AvgExclusiveTime_ColumnTitle", "Average Exclusive Time (ms)")); Column.SetDescription(LOCTEXT("AvgExclusiveTime_ColumnDesc", "Average exclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FAverageExclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::AverageExclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().AverageExclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMedianExclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MedianExclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MedExclusiveTime_ColumnName", "E.Med")); Column.SetTitleName(LOCTEXT("MedExclusiveTime_ColumnTitle", "Median Exclusive Time (ms)")); Column.SetDescription(LOCTEXT("MedExclusiveTime_ColumnDesc", "Median exclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMedianExclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MedianExclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MedianExclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FTimersViewColumnFactory::CreateMinExclusiveTimeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FTimersViewColumns::MinExclusiveTimeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MinExclusiveTime_ColumnName", "E.Min")); Column.SetTitleName(LOCTEXT("MinExclusiveTime_ColumnTitle", "Min Exclusive Time (ms)")); Column.SetDescription(LOCTEXT("MinExclusiveTime_ColumnDesc", "Minimum exclusive duration of selected timer's instances, in milliseconds")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(TimeMsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMinExclusiveTimeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FTimersViewColumns::MinExclusiveTimeColumnID); const FTimerNode& TimerNode = static_cast(Node); return TOptional(FTableCellValue(TimerNode.GetAggregatedStats().MinExclusiveTime)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// #undef LOCTEXT_NAMESPACE