You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Much faster filters due to Async framework, it's paraller now, Optimizations to items rendered on sequencer, Optimization to graphs rendered on canvas, Changed as much as possible to event driven flot, to update data only when needed. [CL 2670708 by sebastian kowalczyk in Main branch]
307 lines
9.8 KiB
C++
307 lines
9.8 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LogVisualizer.h"
|
|
#include "SVisualLoggerView.h"
|
|
#include "TimeSliderController.h"
|
|
#include "ITimeSlider.h"
|
|
#include "STimeSlider.h"
|
|
#include "SSearchBox.h"
|
|
#include "SSequencerSectionOverlay.h"
|
|
#include "STimelinesContainer.h"
|
|
#include "SVisualLoggerLogsList.h"
|
|
#include "LogVisualizerSettings.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "SVisualLoggerLogsList"
|
|
|
|
struct FLogEntryItem
|
|
{
|
|
FString Category;
|
|
FLinearColor CategoryColor;
|
|
ELogVerbosity::Type Verbosity;
|
|
FString Line;
|
|
int64 UserData;
|
|
FName TagName;
|
|
};
|
|
|
|
namespace ELogsSortMode
|
|
{
|
|
enum Type
|
|
{
|
|
ByName,
|
|
ByStartTime,
|
|
ByEndTime,
|
|
};
|
|
}
|
|
|
|
void SVisualLoggerLogsList::Construct(const FArguments& InArgs, const TSharedRef<FUICommandList>& InCommandList)
|
|
{
|
|
ChildSlot
|
|
[
|
|
SAssignNew(LogsLinesWidget, SListView<TSharedPtr<FLogEntryItem> >)
|
|
.ItemHeight(20)
|
|
.ListItemsSource(&CachedLogEntryLines)
|
|
.SelectionMode(ESelectionMode::Multi)
|
|
.OnSelectionChanged(this, &SVisualLoggerLogsList::LogEntryLineSelectionChanged)
|
|
.OnGenerateRow(this, &SVisualLoggerLogsList::LogEntryLinesGenerateRow)
|
|
];
|
|
|
|
FVisualLoggerDatabase::Get().GetEvents().OnItemSelectionChanged.AddRaw(this, &SVisualLoggerLogsList::OnItemSelectionChanged);
|
|
FVisualLoggerDatabase::Get().GetEvents().OnRowSelectionChanged.AddRaw(this, &SVisualLoggerLogsList::ObjectSelectionChanged);
|
|
FLogVisualizer::Get().GetEvents().OnFiltersChanged.AddRaw(this, &SVisualLoggerLogsList::OnFiltersChanged);
|
|
}
|
|
|
|
SVisualLoggerLogsList::~SVisualLoggerLogsList()
|
|
{
|
|
FVisualLoggerDatabase::Get().GetEvents().OnItemSelectionChanged.RemoveAll(this);
|
|
FVisualLoggerDatabase::Get().GetEvents().OnRowSelectionChanged.RemoveAll(this);
|
|
FLogVisualizer::Get().GetEvents().OnFiltersChanged.RemoveAll(this);
|
|
}
|
|
|
|
FReply SVisualLoggerLogsList::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
|
|
{
|
|
if (InKeyEvent.GetKey() == EKeys::C && (InKeyEvent.IsLeftCommandDown() || InKeyEvent.IsLeftControlDown()))
|
|
{
|
|
FString ClipboardString;
|
|
for (const TSharedPtr<struct FLogEntryItem>& CurrentItem : LogsLinesWidget->GetSelectedItems())
|
|
{
|
|
if (CurrentItem->Category.Len() > 0)
|
|
ClipboardString += CurrentItem->Category + FString(TEXT(" (")) + FString(FOutputDevice::VerbosityToString(CurrentItem->Verbosity)) + FString(TEXT(") ")) + CurrentItem->Line;
|
|
else
|
|
ClipboardString += CurrentItem->Line;
|
|
|
|
ClipboardString += TEXT("\n");
|
|
}
|
|
FPlatformMisc::ClipboardCopy(*ClipboardString);
|
|
return FReply::Handled();
|
|
}
|
|
|
|
return SVisualLoggerBaseWidget::OnKeyDown(MyGeometry, InKeyEvent);
|
|
}
|
|
|
|
void SVisualLoggerLogsList::OnFiltersChanged()
|
|
{
|
|
RegenerateLogEntries();
|
|
LogsLinesWidget->RequestListRefresh();
|
|
}
|
|
|
|
TSharedRef<ITableRow> SVisualLoggerLogsList::LogEntryLinesGenerateRow(TSharedPtr<FLogEntryItem> Item, const TSharedRef<STableViewBase>& OwnerTable)
|
|
{
|
|
if (Item->Category.Len() > 0)
|
|
{
|
|
return SNew(STableRow< TSharedPtr<FString> >, OwnerTable)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(FMargin(5.0f, 0.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.ColorAndOpacity(FSlateColor(Item->CategoryColor))
|
|
.Text(FText::FromString(Item->Category))
|
|
.HighlightText(this, &SVisualLoggerLogsList::GetFilterText)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(FMargin(5.0f, 0.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.ColorAndOpacity(FSlateColor(Item->Verbosity == ELogVerbosity::Error ? FLinearColor::Red : (Item->Verbosity == ELogVerbosity::Warning ? FLinearColor::Yellow : FLinearColor::Gray)))
|
|
.Text(FText::FromString(FString(TEXT("(")) + FString(FOutputDevice::VerbosityToString(Item->Verbosity)) + FString(TEXT(")"))))
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.Padding(FMargin(5.0f, 0.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.AutoWrapText(true)
|
|
.ColorAndOpacity(FSlateColor(Item->Verbosity == ELogVerbosity::Error ? FLinearColor::Red : (Item->Verbosity == ELogVerbosity::Warning ? FLinearColor::Yellow : FLinearColor::Gray)))
|
|
.Text(FText::FromString(Item->Line))
|
|
.HighlightText(this, &SVisualLoggerLogsList::GetFilterText)
|
|
.TextStyle(FLogVisualizerStyle::Get(), TEXT("TextLogs.Text"))
|
|
]
|
|
];
|
|
|
|
}
|
|
else
|
|
{
|
|
return SNew(STableRow< TSharedPtr<FString> >, OwnerTable)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot()
|
|
.Padding(FMargin(5.0f, 0.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
/*.AutoWrapText(true)*/
|
|
.ColorAndOpacity(FSlateColor(FLinearColor::White))
|
|
.Text(FText::FromString(Item->Line))
|
|
.HighlightText(this, &SVisualLoggerLogsList::GetFilterText)
|
|
.Justification(ETextJustify::Center)
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
FText SVisualLoggerLogsList::GetFilterText() const
|
|
{
|
|
static FText NoText;
|
|
const bool bSearchInsideLogs = ULogVisualizerSettings::StaticClass()->GetDefaultObject<ULogVisualizerSettings>()->bSearchInsideLogs;
|
|
return bSearchInsideLogs ? FText::FromString(FVisualLoggerFilters::Get().GetSearchString()) : NoText;
|
|
}
|
|
|
|
void SVisualLoggerLogsList::OnFiltersSearchChanged(const FText& Filter)
|
|
{
|
|
OnFiltersChanged();
|
|
}
|
|
|
|
void SVisualLoggerLogsList::LogEntryLineSelectionChanged(TSharedPtr<FLogEntryItem> SelectedItem, ESelectInfo::Type SelectInfo)
|
|
{
|
|
if (SelectedItem.IsValid() == true)
|
|
{
|
|
FLogVisualizer::Get().GetEvents().OnLogLineSelectionChanged.ExecuteIfBound(SelectedItem, SelectedItem->UserData, SelectedItem->TagName);
|
|
}
|
|
else
|
|
{
|
|
FLogVisualizer::Get().GetEvents().OnLogLineSelectionChanged.ExecuteIfBound(SelectedItem, 0, NAME_None);
|
|
}
|
|
}
|
|
|
|
void SVisualLoggerLogsList::ObjectSelectionChanged(const TArray<FName>&)
|
|
{
|
|
RegenerateLogEntries();
|
|
LogsLinesWidget->RequestListRefresh();
|
|
}
|
|
|
|
void SVisualLoggerLogsList::ResetData()
|
|
{
|
|
CachedLogEntryLines.Reset();
|
|
LogsLinesWidget->RequestListRefresh();
|
|
}
|
|
|
|
void SVisualLoggerLogsList::OnItemSelectionChanged(const FVisualLoggerDBRow& BDRow, int32 ItemIndex)
|
|
{
|
|
RegenerateLogEntries();
|
|
}
|
|
|
|
void SVisualLoggerLogsList::RegenerateLogEntries()
|
|
{
|
|
CachedLogEntryLines.Reset();
|
|
|
|
const TArray<FName> SelectedRows = FVisualLoggerDatabase::Get().GetSelectedRows();
|
|
for (FName CurrentRow : SelectedRows)
|
|
{
|
|
if (FVisualLoggerDatabase::Get().IsRowVisible(CurrentRow) == false)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const FVisualLoggerDBRow& DBRow = FVisualLoggerDatabase::Get().GetRowByName(CurrentRow);
|
|
const TArray<FVisualLogDevice::FVisualLogEntryItem>& Entries = FVisualLoggerDatabase::Get().GetRowByName(CurrentRow).GetItems();
|
|
|
|
int32 BestItemIndex = INDEX_NONE;
|
|
float BestDistance = MAX_FLT;
|
|
for (int32 Index = 0; Index < Entries.Num(); Index++)
|
|
{
|
|
auto& CurrentEntryItem = Entries[Index];
|
|
if (DBRow.IsItemVisible(Index) == false)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TArray<FVisualLoggerCategoryVerbosityPair> OutCategories;
|
|
const float CurrentDist = DBRow.GetCurrentItemIndex() == INDEX_NONE ? 0 : FMath::Abs(CurrentEntryItem.Entry.TimeStamp - DBRow.GetCurrentItem().Entry.TimeStamp);
|
|
if (CurrentDist < BestDistance)
|
|
{
|
|
BestDistance = CurrentDist;
|
|
BestItemIndex = Index;
|
|
}
|
|
}
|
|
|
|
if (Entries.IsValidIndex(BestItemIndex))
|
|
{
|
|
GenerateLogs(Entries[BestItemIndex], SelectedRows.Num() > 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SVisualLoggerLogsList::GenerateLogs(const FVisualLogDevice::FVisualLogEntryItem& LogEntry, bool bGenerateHeader)
|
|
{
|
|
TArray<FVisualLoggerCategoryVerbosityPair> OutCategories;
|
|
FVisualLoggerHelpers::GetCategories(LogEntry.Entry, OutCategories);
|
|
bool bHasValidCategory = false;
|
|
for (auto& CurrentCategory : OutCategories)
|
|
{
|
|
bHasValidCategory |= FVisualLoggerFilters::Get().MatchCategoryFilters(CurrentCategory.CategoryName.ToString(), CurrentCategory.Verbosity);
|
|
}
|
|
|
|
if (!bHasValidCategory)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bGenerateHeader)
|
|
{
|
|
FLogEntryItem EntryItem;
|
|
EntryItem.Category = FString();
|
|
EntryItem.CategoryColor = FLinearColor::Black;
|
|
EntryItem.Verbosity = ELogVerbosity::VeryVerbose;
|
|
EntryItem.Line = LogEntry.OwnerName.ToString();
|
|
EntryItem.UserData = 0;
|
|
EntryItem.TagName = NAME_None;
|
|
CachedLogEntryLines.Add(MakeShareable(new FLogEntryItem(EntryItem)));
|
|
}
|
|
|
|
const FVisualLogLine* LogLine = LogEntry.Entry.LogLines.GetData();
|
|
const bool bSearchInsideLogs = ULogVisualizerSettings::StaticClass()->GetDefaultObject<ULogVisualizerSettings>()->bSearchInsideLogs;
|
|
for (int LineIndex = 0; LineIndex < LogEntry.Entry.LogLines.Num(); ++LineIndex, ++LogLine)
|
|
{
|
|
bool bShowLine = FVisualLoggerFilters::Get().MatchCategoryFilters(LogLine->Category.ToString(), LogLine->Verbosity);
|
|
if (bSearchInsideLogs)
|
|
{
|
|
FString String = FVisualLoggerFilters::Get().GetSearchString();
|
|
if (String.Len() > 0)
|
|
{
|
|
bShowLine &= LogLine->Line.Find(String) != INDEX_NONE || LogLine->Category.ToString().Find(String) != INDEX_NONE;
|
|
}
|
|
}
|
|
|
|
|
|
if (bShowLine)
|
|
{
|
|
FLogEntryItem EntryItem;
|
|
EntryItem.Category = LogLine->Category.ToString();
|
|
EntryItem.CategoryColor = FLogVisualizer::Get().GetColorForCategory(LogLine->Category.ToString());
|
|
EntryItem.Verbosity = LogLine->Verbosity;
|
|
EntryItem.Line = LogLine->Line;
|
|
EntryItem.UserData = LogLine->UserData;
|
|
EntryItem.TagName = LogLine->TagName;
|
|
|
|
CachedLogEntryLines.Add(MakeShareable(new FLogEntryItem(EntryItem)));
|
|
}
|
|
}
|
|
|
|
for (auto& Event : LogEntry.Entry.Events)
|
|
{
|
|
bool bShowLine = FVisualLoggerFilters::Get().MatchCategoryFilters(Event.Name, Event.Verbosity);
|
|
|
|
if (bShowLine)
|
|
{
|
|
FLogEntryItem EntryItem;
|
|
EntryItem.Category = Event.Name;
|
|
EntryItem.CategoryColor = FLogVisualizer::Get().GetColorForCategory(*EntryItem.Category);
|
|
EntryItem.Verbosity = Event.Verbosity;
|
|
EntryItem.Line = FString::Printf(TEXT("Registered event: '%s' (%d times)%s"), *Event.Name, Event.Counter, Event.EventTags.Num() ? TEXT("\n") : TEXT(""));
|
|
for (auto& EventTag : Event.EventTags)
|
|
{
|
|
EntryItem.Line += FString::Printf(TEXT("%d times for tag: '%s'\n"), EventTag.Value, *EventTag.Key.ToString());
|
|
}
|
|
EntryItem.UserData = Event.UserData;
|
|
EntryItem.TagName = Event.TagName;
|
|
|
|
CachedLogEntryLines.Add(MakeShareable(new FLogEntryItem(EntryItem)));
|
|
}
|
|
|
|
}
|
|
|
|
LogsLinesWidget->RequestListRefresh();
|
|
}
|
|
#undef LOCTEXT_NAMESPACE
|