CogEngine: Plot window tweaks

This commit is contained in:
Arnaud Jamin
2025-01-17 02:03:51 -05:00
parent 4451e6bc50
commit 6d8f7cb975
4 changed files with 268 additions and 153 deletions
@@ -8,25 +8,28 @@
FCogDebugPlotEvent FCogDebugPlot::DefaultEvent; FCogDebugPlotEvent FCogDebugPlot::DefaultEvent;
TArray<FCogDebugPlotEntry> FCogDebugPlot::Plots; TArray<FCogDebugPlotEntry> FCogDebugPlot::Plots;
TArray<FCogDebugPlotEntry> FCogDebugPlot::Events;
bool FCogDebugPlot::IsVisible = false; bool FCogDebugPlot::IsVisible = false;
bool FCogDebugPlot::Pause = false; bool FCogDebugPlot::Pause = false;
FName FCogDebugPlot::LastAddedEventPlotName = NAME_None; FName FCogDebugPlot::LastAddedEventPlotName = NAME_None;
int32 FCogDebugPlot::LastAddedEventIndex = INDEX_NONE; int32 FCogDebugPlot::LastAddedEventIndex = INDEX_NONE;
TMap<int32, int32> FCogDebugPlot::OccupiedRowMap; TMap<int32, TMap<int32, int32>> FCogDebugPlot::OccupationMap;
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
// FCogPlotEvent // FCogPlotEvent
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
float FCogDebugPlotEvent::GetActualEndTime(const FCogDebugPlotEntry& Plot) const float FCogDebugPlotEvent::GetActualEndTime(const FCogDebugPlotEntry& Plot) const
{ {
const float ActualEndTime = EndTime == 0.0f ? Plot.Time : EndTime; const UWorld* World = Plot.World.Get();
const float WorldTime = World != nullptr ? World->GetTimeSeconds() : 0.0f;
const float ActualEndTime = EndTime != 0.0f ? EndTime : WorldTime;
return ActualEndTime; return ActualEndTime;
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
uint64 FCogDebugPlotEvent::GetActualEndFrame(const FCogDebugPlotEntry& Plot) const uint64 FCogDebugPlotEvent::GetActualEndFrame(const FCogDebugPlotEntry& Plot) const
{ {
const float ActualEndFame = EndFrame == 0.0f ? Plot.Frame : EndFrame; const float ActualEndFame = EndFrame != 0.0f ? EndFrame : GFrameCounter;
return ActualEndFame; return ActualEndFame;
} }
@@ -119,9 +122,8 @@ void FCogDebugPlotEntry::AddPoint(float X, float Y)
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent( FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent(
const FCogDebugPlotEntry& OwnwePlot, const FString& OwnerName,
FString OwnerName, const bool IsInstant,
bool IsInstant,
const FName EventId, const FName EventId,
const int32 Row, const int32 Row,
const FColor& Color) const FColor& Color)
@@ -132,7 +134,7 @@ FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent(
} }
//---------------------------- //----------------------------
// Stop if any already exist. // Stop if it already exist.
//---------------------------- //----------------------------
StopEvent(EventId); StopEvent(EventId);
@@ -154,15 +156,15 @@ FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent(
Event->Id = EventId; Event->Id = EventId;
Event->OwnerName = OwnerName; Event->OwnerName = OwnerName;
Event->DisplayName = EventId.ToString(); Event->DisplayName = EventId.ToString();
Event->StartTime = OwnwePlot.Time; Event->StartTime = Time;
Event->EndTime = IsInstant ? OwnwePlot.Time : 0.0f; Event->EndTime = IsInstant ? Time : 0.0f;
Event->StartFrame = OwnwePlot.Frame; Event->StartFrame = Frame;
Event->EndFrame = IsInstant ? OwnwePlot.Frame : 0.0f; Event->EndFrame = IsInstant ? Frame : 0.0f;
Event->Row = (Row == FCogDebugPlot::AutoRow) ? FCogDebugPlot::FindFreeEventRow() : Row; Event->Row = (Row == FCogDebugPlot::AutoRow) ? FCogDebugPlot::FindFreeGraphRow(GraphIndex) : Row;
if (IsInstant == false) if (IsInstant == false)
{ {
FCogDebugPlot::OccupyRow(Event->Row); FCogDebugPlot::OccupyGraphRow(GraphIndex, Event->Row);
} }
MaxRow = FMath::Max(Event->Row, MaxRow); MaxRow = FMath::Max(Event->Row, MaxRow);
@@ -172,7 +174,7 @@ FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent(
Event->BorderColor = FCogImguiHelper::ToImColor(BorderColor); Event->BorderColor = FCogImguiHelper::ToImColor(BorderColor);
Event->FillColor = FCogImguiHelper::ToImColor(FillColor); Event->FillColor = FCogImguiHelper::ToImColor(FillColor);
FCogDebugPlot::LastAddedEventPlotName = OwnwePlot.Name; FCogDebugPlot::LastAddedEventPlotName = Name;
FCogDebugPlot::LastAddedEventIndex = AddedIndex; FCogDebugPlot::LastAddedEventIndex = AddedIndex;
return *Event; return *Event;
@@ -192,19 +194,12 @@ FCogDebugPlotEvent& FCogDebugPlotEntry::StopEvent(const FName EventId)
Event->EndTime = Time; Event->EndTime = Time;
Event->EndFrame = Frame; Event->EndFrame = Frame;
FCogDebugPlot::FreeRow(Event->Row); FCogDebugPlot::FreeGraphRow(GraphIndex, Event->Row);
} }
return *Event; return *Event;
} }
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::UpdateTime(const UWorld* World)
{
Time = World ? World->GetTimeSeconds() : 0.0;
Frame = GFrameCounter;
}
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent* FCogDebugPlotEntry::GetLastEvent() FCogDebugPlotEvent* FCogDebugPlotEntry::GetLastEvent()
{ {
@@ -246,17 +241,17 @@ FCogDebugPlotEvent* FCogDebugPlotEntry::FindLastEventByName(FName EventId)
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::AssignAxis(int32 Row, ImAxis YAxis) void FCogDebugPlotEntry::AssignGraphAndAxis(int32 InGraph, ImAxis InYAxis)
{ {
CurrentRow = Row; GraphIndex = InGraph;
CurrentYAxis = YAxis; YAxis = InYAxis;
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::ResetAxis() void FCogDebugPlotEntry::ResetGraphAndAxis()
{ {
CurrentRow = INDEX_NONE; GraphIndex = INDEX_NONE;
CurrentYAxis = ImAxis_COUNT; YAxis = ImAxis_COUNT;
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@@ -326,7 +321,8 @@ bool FCogDebugPlotEntry::FindValue(float x, float& y) const
void FCogDebugPlot::Reset() void FCogDebugPlot::Reset()
{ {
Plots.Empty(); Plots.Empty();
OccupiedRowMap.Empty(); Events.Empty();
OccupationMap.Empty();
Pause = false; Pause = false;
ResetLastAddedEvent(); ResetLastAddedEvent();
} }
@@ -339,7 +335,12 @@ void FCogDebugPlot::Clear()
Entry.Clear(); Entry.Clear();
} }
OccupiedRowMap.Empty(); for (FCogDebugPlotEntry& Entry : Events)
{
Entry.Clear();
}
OccupationMap.Empty();
ResetLastAddedEvent(); ResetLastAddedEvent();
} }
@@ -353,7 +354,7 @@ void FCogDebugPlot::ResetLastAddedEvent()
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent* FCogDebugPlot::GetLastAddedEvent() FCogDebugPlotEvent* FCogDebugPlot::GetLastAddedEvent()
{ {
FCogDebugPlotEntry* Plot = FindPlot(LastAddedEventPlotName); FCogDebugPlotEntry* Plot = FindEntry(true, LastAddedEventPlotName);
if (Plot == nullptr) if (Plot == nullptr)
{ {
return nullptr; return nullptr;
@@ -363,10 +364,27 @@ FCogDebugPlotEvent* FCogDebugPlot::GetLastAddedEvent()
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEntry* FCogDebugPlot::FindPlot(const FName Name) FCogDebugPlotEntry* FCogDebugPlot::FindEntry(const FName Name)
{ {
FCogDebugPlotEntry* Plot = Plots.FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; }); if (FCogDebugPlotEntry* Event = Events.FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; }))
return Plot; {
return Event;
}
if (FCogDebugPlotEntry* Plot = Plots.FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; }))
{
return Plot;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEntry* FCogDebugPlot::FindEntry(bool IsEvent, const FName Name)
{
TArray<FCogDebugPlotEntry>* Entries = IsEvent ? &Events : &Plots;
FCogDebugPlotEntry* Entry = Entries->FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; });
return Entry;
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@@ -391,19 +409,20 @@ FCogDebugPlotEntry* FCogDebugPlot::RegisterPlot(const UObject* WorldContextObjec
return nullptr; return nullptr;
} }
FCogDebugPlotEntry* EntryPtr = FindPlot(PlotName); FCogDebugPlotEntry* EntryPtr = FindEntry(IsEventPlot, PlotName);
if (EntryPtr == nullptr) if (EntryPtr == nullptr)
{ {
EntryPtr = &Plots.AddDefaulted_GetRef(); TArray<FCogDebugPlotEntry>* Entries = IsEventPlot ? &Events : &Plots;
EntryPtr = &Entries->AddDefaulted_GetRef();
EntryPtr->Name = PlotName; EntryPtr->Name = PlotName;
EntryPtr->IsEventPlot = IsEventPlot; EntryPtr->IsEventPlot = IsEventPlot;
Plots.Sort([](const FCogDebugPlotEntry& A, const FCogDebugPlotEntry& B) { return A.Name.ToString().Compare(B.Name.ToString()) < 0; }); Entries->Sort([](const FCogDebugPlotEntry& A, const FCogDebugPlotEntry& B) { return A.Name.ToString().Compare(B.Name.ToString()) < 0; });
} }
if (EntryPtr->CurrentYAxis == ImAxis_COUNT) //if (EntryPtr->YAxis == ImAxis_COUNT)
{ //{
return nullptr; // return nullptr;
} //}
const float Time = World->GetTimeSeconds(); const float Time = World->GetTimeSeconds();
if (Time < EntryPtr->Time) if (Time < EntryPtr->Time)
@@ -411,6 +430,7 @@ FCogDebugPlotEntry* FCogDebugPlot::RegisterPlot(const UObject* WorldContextObjec
EntryPtr->Clear(); EntryPtr->Clear();
} }
EntryPtr->World = World;
EntryPtr->Time = World->GetTimeSeconds(); EntryPtr->Time = World->GetTimeSeconds();
EntryPtr->Frame = GFrameCounter; EntryPtr->Frame = GFrameCounter;
@@ -439,7 +459,7 @@ FCogDebugPlotEvent& FCogDebugPlot::PlotEvent(const UObject* WorldContextObject,
return DefaultEvent; return DefaultEvent;
} }
FCogDebugPlotEvent& Event = Plot->AddEvent(*Plot, GetNameSafe(WorldContextObject), IsInstant, EventId, Row, Color); FCogDebugPlotEvent& Event = Plot->AddEvent(GetNameSafe(WorldContextObject), IsInstant, EventId, Row, Color);
return Event; return Event;
} }
@@ -485,36 +505,50 @@ FCogDebugPlotEvent& FCogDebugPlot::PlotEventToggle(const UObject* WorldContextOb
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::OccupyRow(const int32 Row) void FCogDebugPlot::OccupyGraphRow(const int32 InGraphIndex, const int32 InRow)
{ {
if (int32* RowOccupation = OccupiedRowMap.Find(Row)) TMap<int32, int32>& GraphOccupation = OccupationMap.FindOrAdd(InGraphIndex);
if (int32* RowOccupation = GraphOccupation.Find(InRow))
{ {
(*RowOccupation)++; (*RowOccupation)++;
} }
else else
{ {
OccupiedRowMap.Add(Row, 1); GraphOccupation.Add(InRow, 1);
} }
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::FreeRow(const int32 Row) void FCogDebugPlot::FreeGraphRow(const int32 InGraphIndex, const int32 Row)
{ {
if (int32* RowOccupation = OccupiedRowMap.Find(Row)) TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InGraphIndex);
{ if (GraphOccupation == nullptr)
(*RowOccupation)--; { return; }
}
int32* RowOccupation = GraphOccupation->Find(Row);
if (RowOccupation == nullptr)
{ return; }
(*RowOccupation)--;
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
int32 FCogDebugPlot::FindFreeEventRow() int32 FCogDebugPlot::FindFreeGraphRow(const int32 InGraphIndex)
{ {
constexpr int32 MaxRows = 100; constexpr int32 MaxRows = 100;
int32 FreeRow = 0; int32 FreeRow = 0;
TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InGraphIndex);
if (GraphOccupation == nullptr)
{
return FreeRow;
}
for (; FreeRow < MaxRows; ++FreeRow) for (; FreeRow < MaxRows; ++FreeRow)
{ {
const int32* Occupation = OccupiedRowMap.Find(FreeRow); const int32* Occupation = GraphOccupation->Find(FreeRow);
if (Occupation == nullptr || *Occupation == 0) if (Occupation == nullptr || *Occupation == 0)
{ {
break; break;
@@ -49,37 +49,56 @@ struct COGDEBUG_API FCogDebugPlotEvent
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugPlotEntry struct COGDEBUG_API FCogDebugPlotEntry
{ {
void AssignAxis(int32 AssignedRow, ImAxis CurrentYAxis); void AssignGraphAndAxis(int32 AssignedRow, ImAxis CurrentYAxis);
void AddPoint(float X, float Y);
void AddPoint(float X, float Y);
bool FindValue(float Time, float& Value) const; bool FindValue(float Time, float& Value) const;
void ResetAxis();
void Clear(); void ResetGraphAndAxis();
FCogDebugPlotEvent& AddEvent(const FCogDebugPlotEntry& OwnwePlot, FString OwnerName, bool IsInstant, const FName EventId, const int32 Row, const FColor& Color);
FCogDebugPlotEvent& StopEvent(const FName EventId); void Clear();
void UpdateTime(const UWorld* World);
FCogDebugPlotEvent* GetLastEvent(); FCogDebugPlotEvent& AddEvent(const FString& OwnerName, bool IsInstant, const FName EventId, const int32 Row, const FColor& Color);
FCogDebugPlotEvent* FindLastEventByName(FName EventId);
FCogDebugPlotEvent& StopEvent(const FName EventId);
FCogDebugPlotEvent* GetLastEvent();
FCogDebugPlotEvent* FindLastEventByName(FName EventId);
FName Name; FName Name;
bool IsEventPlot = false;
int32 CurrentRow = INDEX_NONE; bool IsEventPlot = false;
ImAxis CurrentYAxis = ImAxis_COUNT;
float Time = 0; int32 GraphIndex = INDEX_NONE;
uint64 Frame = 0;
ImAxis YAxis = ImAxis_COUNT;
float Time = 0;
uint64 Frame = 0;
TWeakObjectPtr<const UWorld> World;
//-------------------------- //--------------------------
// Values // Values
//-------------------------- //--------------------------
int32 ValueOffset = 0; int32 ValueOffset = 0;
ImVector<ImVec2> Values;
bool ShowValuesMarkers = false; ImVector<ImVec2> Values;
bool ShowValuesMarkers = false;
//-------------------------- //--------------------------
// Events // Events
//-------------------------- //--------------------------
int32 EventOffset = 0; int32 EventOffset = 0;
TArray<FCogDebugPlotEvent> Events;
int32 MaxRow = 1; TArray<FCogDebugPlotEvent> Events;
int32 MaxRow = 1;
}; };
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@@ -87,21 +106,34 @@ struct COGDEBUG_API FCogDebugPlotEntry
class COGDEBUG_API FCogDebugPlot class COGDEBUG_API FCogDebugPlot
{ {
public: public:
static const int32 AutoRow = -1; static constexpr int32 AutoRow = -1;
static void PlotValue(const UObject* WorldContextObject, const FName PlotName, const float Value); static void PlotValue(const UObject* WorldContextObject, const FName PlotName, const float Value);
static FCogDebugPlotEvent& PlotEvent(const UObject* WorldContextObject, const FName PlotName, const FName EventId, bool IsInstant, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent); static FCogDebugPlotEvent& PlotEvent(const UObject* WorldContextObject, const FName PlotName, const FName EventId, bool IsInstant, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventInstant(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent); static FCogDebugPlotEvent& PlotEventInstant(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventStart(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent); static FCogDebugPlotEvent& PlotEventStart(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventStop(const UObject* WorldContextObject, const FName PlotName, const FName EventId); static FCogDebugPlotEvent& PlotEventStop(const UObject* WorldContextObject, const FName PlotName, const FName EventId);
static FCogDebugPlotEvent& PlotEventToggle(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const bool ToggleValue, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent); static FCogDebugPlotEvent& PlotEventToggle(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const bool ToggleValue, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static void Reset(); static void Reset();
static void Clear(); static void Clear();
static FCogDebugPlotEntry* FindPlot(const FName Name);
static FCogDebugPlotEntry* FindEntry(const FName Name);
static FCogDebugPlotEntry* FindEntry(bool IsEvent, const FName Name);
static TArray<FCogDebugPlotEntry> Plots; static TArray<FCogDebugPlotEntry> Plots;
static TArray<FCogDebugPlotEntry> Events;
static bool IsVisible; static bool IsVisible;
static bool Pause; static bool Pause;
private: private:
@@ -113,11 +145,11 @@ private:
static FCogDebugPlotEvent* GetLastAddedEvent(); static FCogDebugPlotEvent* GetLastAddedEvent();
static void OccupyRow(const int32 Row); static void OccupyGraphRow(const int32 InGraphIndex, const int32 InRow);
static void FreeRow(const int32 Row); static void FreeGraphRow(const int32 InGraphIndex, const int32 InRow);
static int32 FindFreeEventRow(); static int32 FindFreeGraphRow(const int32 InGraphIndex);
static FName LastAddedEventPlotName; static FName LastAddedEventPlotName;
@@ -125,7 +157,8 @@ private:
static FCogDebugPlotEvent DefaultEvent; static FCogDebugPlotEvent DefaultEvent;
static TMap<int32, int32> OccupiedRowMap; // graph index to row index to number of objects occupying the row
static TMap<int32, TMap<int32, int32>> OccupationMap;
}; };
#endif //ENABLE_COG #endif //ENABLE_COG
@@ -16,6 +16,8 @@ void FCogEngineWindow_Plots::Initialize()
bNoPadding = true; bNoPadding = true;
Config = GetConfig<UCogEngineConfig_Plots>(); Config = GetConfig<UCogEngineConfig_Plots>();
FCogDebugPlot::Clear();
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@@ -50,15 +52,23 @@ void FCogEngineWindow_Plots::RenderContent()
TArray<FCogDebugPlotEntry*> VisiblePlots; TArray<FCogDebugPlotEntry*> VisiblePlots;
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots) for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
{ {
if (Plot.CurrentYAxis != ImAxis_COUNT && Plot.CurrentRow != INDEX_NONE) if (Plot.YAxis != ImAxis_COUNT && Plot.GraphIndex != INDEX_NONE)
{ {
VisiblePlots.Add(&Plot); VisiblePlots.Add(&Plot);
} }
} }
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
{
if (Event.YAxis != ImAxis_COUNT && Event.GraphIndex != INDEX_NONE)
{
VisiblePlots.Add(&Event);
}
}
RenderMenu(); RenderMenu();
if (Config->DockPlotList) if (Config->DockEntries)
{ {
if (ImGui::BeginTable("PlotTable", 2, ImGuiTableFlags_RowBg if (ImGui::BeginTable("PlotTable", 2, ImGuiTableFlags_RowBg
| ImGuiTableFlags_Resizable | ImGuiTableFlags_Resizable
@@ -73,7 +83,7 @@ void FCogEngineWindow_Plots::RenderContent()
ImGui::TableNextColumn(); ImGui::TableNextColumn();
RenderPlotsList(ImVec2(0, -1)); RenderAllEntriesNames(ImVec2(0, -1));
ImGui::TableNextColumn(); ImGui::TableNextColumn();
RenderPlots(VisiblePlots); RenderPlots(VisiblePlots);
@@ -95,11 +105,11 @@ void FCogEngineWindow_Plots::RenderMenu()
{ {
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
if (Config->DockPlotList == false) if (Config->DockEntries == false)
{ {
if (ImGui::BeginMenu("Plots")) if (ImGui::BeginMenu("Entries"))
{ {
RenderPlotsList(ImVec2(ImGui::GetFontSize() * 15, ImGui::GetFontSize() * 20)); RenderAllEntriesNames(ImVec2(ImGui::GetFontSize() * 15, ImGui::GetFontSize() * 20));
ImGui::EndMenu(); ImGui::EndMenu();
} }
} }
@@ -122,13 +132,13 @@ void FCogEngineWindow_Plots::RenderMenu()
} }
FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 30.0f, "%0.1f")) if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 100.0f, "%0.1f"))
{ {
bApplyTimeScale = true; bApplyTimeScale = true;
} }
FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Drag view sensitivity", &Config->DragViewSensitivity, 1.0f, 50.0f, "%0.0f"); ImGui::SliderFloat("Drag pause sensitivity", &Config->DragPauseSensitivity, 1.0f, 50.0f, "%0.0f");
FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Show time bar at game time", &Config->ShowTimeBarAtGameTime); ImGui::Checkbox("Show time bar at game time", &Config->ShowTimeBarAtGameTime);
@@ -140,7 +150,7 @@ void FCogEngineWindow_Plots::RenderMenu()
ImGui::Checkbox("Show value at cursor", &Config->ShowValueAtCursor); ImGui::Checkbox("Show value at cursor", &Config->ShowValueAtCursor);
FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Dock plots", &Config->DockPlotList); ImGui::Checkbox("Dock entries", &Config->DockEntries);
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf; constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("Pause background color", Config->PauseBackgroundColor, ColorEditFlags); FCogImguiHelper::ColorEdit4("Pause background color", Config->PauseBackgroundColor, ColorEditFlags);
@@ -161,48 +171,90 @@ void FCogEngineWindow_Plots::RenderMenu()
} }
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderPlotsList(const ImVec2& InSize) void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugPlotEntry& Entry)
{ {
if (ImGui::BeginChild("Plots", InSize)) ImGui::PushID(Index);
const bool IsAssignedToRow = Entry.GraphIndex != INDEX_NONE;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Name.ToString()), IsAssignedToRow, ImGuiSelectableFlags_AllowDoubleClick))
{
if (IsAssignedToRow)
{
Entry.ResetGraphAndAxis();
}
else
{
Entry.AssignGraphAndAxis(0, ImAxis_Y1);
}
}
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
{
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
ImGui::Text("%s", EntryName.Get());
ImGui::EndDragDropSource();
}
ImGui::PopID();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderAllEntriesNames(const ImVec2& InSize)
{
if (ImGui::BeginChild("Entries", InSize))
{ {
int Index = 0; if (Config->DockEntries)
ImGui::Indent(6);
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
{ {
ImGui::PushID(Index); ImGui::Indent(6);
ImGui::PushStyleColor(ImGuiCol_Text, Plot.IsEventPlot ? IM_COL32(128, 128, 255, 255) : IM_COL32(255, 255, 255, 255));
const bool IsAssignedToRow = Plot.CurrentRow != INDEX_NONE;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Plot.Name.ToString()), IsAssignedToRow, ImGuiSelectableFlags_AllowDoubleClick))
{
if (IsAssignedToRow)
{
Plot.ResetAxis();
}
else
{
Plot.AssignAxis(0, ImAxis_Y1);
}
}
ImGui::PopStyleColor();
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
{
const auto EntryName = StringCast<ANSICHAR>(*Plot.Name.ToString());
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
ImGui::Text("%s", EntryName.Get());
ImGui::EndDragDropSource();
}
ImGui::PopID();
Index++;
} }
ImGui::Unindent(); int Index = 0;
ImGui::PushStyleColor(ImGuiCol_Header, IM_COL32(66, 66, 66, 79));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, IM_COL32(62, 62, 62, 204));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, IM_COL32(86, 86, 86, 255));
if (ImGui::CollapsingHeader("Events", ImGuiTreeNodeFlags_DefaultOpen))
{
if (FCogDebugPlot::Events.IsEmpty())
{
ImGui::TextDisabled("No event added yet");
}
else
{
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
{
RenderEntryName(Index, Event);
Index++;
}
}
}
ImGui::PopStyleColor(3);
ImGui::PushStyleColor(ImGuiCol_Header, IM_COL32(66, 66, 66, 79));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, IM_COL32(62, 62, 62, 204));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, IM_COL32(86, 86, 86, 255));
if (ImGui::CollapsingHeader("Plots", ImGuiTreeNodeFlags_DefaultOpen))
{
if (FCogDebugPlot::Plots.IsEmpty())
{
ImGui::TextDisabled("No plot added yet");
}
else
{
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
{
RenderEntryName(Index, Plot);
Index++;
}
}
}
ImGui::PopStyleColor(3);
if (Config->DockEntries)
{
ImGui::Unindent();
}
} }
ImGui::EndChild(); ImGui::EndChild();
@@ -210,9 +262,9 @@ void FCogEngineWindow_Plots::RenderPlotsList(const ImVec2& InSize)
{ {
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop")) if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{ {
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data))) if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{ {
Plot->ResetAxis(); Plot->ResetGraphAndAxis();
} }
} }
ImGui::EndDragDropTarget(); ImGui::EndDragDropTarget();
@@ -246,9 +298,9 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots) for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
{ {
HasPlotOnAxisY1 |= PlotPtr->CurrentYAxis == ImAxis_Y1 && PlotPtr->CurrentRow == PlotIndex; HasPlotOnAxisY1 |= PlotPtr->YAxis == ImAxis_Y1 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY2 |= PlotPtr->CurrentYAxis == ImAxis_Y2 && PlotPtr->CurrentRow == PlotIndex; HasPlotOnAxisY2 |= PlotPtr->YAxis == ImAxis_Y2 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY3 |= PlotPtr->CurrentYAxis == ImAxis_Y3 && PlotPtr->CurrentRow == PlotIndex; HasPlotOnAxisY3 |= PlotPtr->YAxis == ImAxis_Y3 && PlotPtr->GraphIndex == PlotIndex;
} }
ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines); ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines);
@@ -297,12 +349,12 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
if (PlotPtr == nullptr) if (PlotPtr == nullptr)
{ continue; } { continue; }
if (PlotPtr->CurrentRow != PlotIndex) if (PlotPtr->GraphIndex != PlotIndex)
{ continue; } { continue; }
if (PlotPtr->IsEventPlot) if (PlotPtr->IsEventPlot)
{ {
ImPlot::SetupAxisLimits(PlotPtr->CurrentYAxis, 0, PlotPtr->MaxRow + 2, ImGuiCond_Always); ImPlot::SetupAxisLimits(PlotPtr->YAxis, 0, PlotPtr->MaxRow + 2, ImGuiCond_Always);
} }
} }
} }
@@ -322,7 +374,7 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
&& ImGui::GetDragDropPayload() == nullptr) && ImGui::GetDragDropPayload() == nullptr)
{ {
const ImVec2 Drag = ImGui::GetMouseDragDelta(0); const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
if (FMath::Abs(Drag.x) > Config->DragViewSensitivity) if (FMath::Abs(Drag.x) > Config->DragPauseSensitivity)
{ {
FCogDebugPlot::Pause = true; FCogDebugPlot::Pause = true;
} }
@@ -366,10 +418,10 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{ continue; } { continue; }
FCogDebugPlotEntry& Plot = *PlotPtr; FCogDebugPlotEntry& Plot = *PlotPtr;
if (Plot.CurrentRow != PlotIndex) if (Plot.GraphIndex != PlotIndex)
{ continue; } { continue; }
ImPlot::SetAxis(Plot.CurrentYAxis); ImPlot::SetAxis(Plot.YAxis);
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL); ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString()); const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString());
@@ -408,9 +460,9 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{ {
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop")) if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{ {
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data))) if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{ {
Plot->AssignAxis(PlotIndex, ImAxis_Y1); Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
} }
} }
ImPlot::EndDragDropTarget(); ImPlot::EndDragDropTarget();
@@ -425,9 +477,9 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{ {
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop")) if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{ {
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data))) if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{ {
Plot->AssignAxis(PlotIndex, y); Plot->AssignGraphAndAxis(PlotIndex, y);
} }
} }
ImPlot::EndDragDropTarget(); ImPlot::EndDragDropTarget();
@@ -441,9 +493,9 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{ {
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop")) if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{ {
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindPlot(FName((const char*)Payload->Data))) if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{ {
Plot->AssignAxis(PlotIndex, ImAxis_Y1); Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
} }
} }
ImPlot::EndDragDropTarget(); ImPlot::EndDragDropTarget();
@@ -514,14 +566,8 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
const ImVec2 Mouse = ImGui::GetMousePos(); const ImVec2 Mouse = ImGui::GetMousePos();
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList(); ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
//--------------------------------------------------------------------
// Update plot time for events as events are not pushed every frames
//--------------------------------------------------------------------
Entry.UpdateTime(GetWorld());
ImPlot::PushPlotClipRect(); ImPlot::PushPlotClipRect();
//---------------------------------------------------------------- //----------------------------------------------------------------
// Plot line only to make the plotter move in time and auto scale // Plot line only to make the plotter move in time and auto scale
//---------------------------------------------------------------- //----------------------------------------------------------------
@@ -26,15 +26,17 @@ protected:
virtual void RenderContent() override; virtual void RenderContent() override;
static void RenderPlotsList(const ImVec2& InSize); virtual void RenderAllEntriesNames(const ImVec2& InSize);
void RenderPlots(const TArray<FCogDebugPlotEntry*>& VisiblePlots) const; virtual void RenderEntryName(const int Index, FCogDebugPlotEntry& Entry);
void RenderMenu(); virtual void RenderPlots(const TArray<FCogDebugPlotEntry*>& VisiblePlots) const;
void RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const; virtual void RenderMenu();
void RenderEvents(FCogDebugPlotEntry& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const; virtual void RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const;
virtual void RenderEvents(FCogDebugPlotEntry& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const;
static void RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry); static void RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry);
@@ -70,13 +72,13 @@ public:
bool ShowValueAtCursor = true; bool ShowValueAtCursor = true;
UPROPERTY(Config) UPROPERTY(Config)
float DragViewSensitivity = 10.0f; float DragPauseSensitivity = 10.0f;
UPROPERTY(Config) UPROPERTY(Config)
FColor PauseBackgroundColor = FColor(10, 0, 0, 255); FColor PauseBackgroundColor = FColor(10, 0, 0, 255);
UPROPERTY(Config) UPROPERTY(Config)
bool DockPlotList = false; bool DockEntries = false;
virtual void Reset() override virtual void Reset() override
{ {
@@ -85,8 +87,8 @@ public:
ShowTimeBarAtGameTime = true; ShowTimeBarAtGameTime = true;
ShowTimeBarAtCursor = true; ShowTimeBarAtCursor = true;
ShowValueAtCursor = true; ShowValueAtCursor = true;
DragViewSensitivity = 10.0f; DragPauseSensitivity = 10.0f;
PauseBackgroundColor = FColor(10, 0, 0, 255); PauseBackgroundColor = FColor(10, 0, 0, 255);
DockPlotList = false; DockEntries = false;
} }
}; };