// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Fonts/SlateFontInfo.h" #include "TraceServices/Model/NetProfiler.h" #include "Styling/WidgetStyle.h" enum class ESlateDrawEffect : uint8; struct FDrawContext; struct FGeometry; struct FSlateBrush; class FPacketContentViewport; class FSlateWindowElementList; //////////////////////////////////////////////////////////////////////////////////////////////////// struct FNetworkPacketEvent { uint32 EventTypeIndex; uint32 ObjectInstanceIndex; uint32 NetId; uint32 BitOffset; uint32 BitSize; uint32 Level; FNetworkPacketEvent() : EventTypeIndex(0), ObjectInstanceIndex(0), NetId(0), BitOffset(0), BitSize(0), Level(0) {} FNetworkPacketEvent(uint32 InEventTypeIndex, uint32 InObjectInstanceIndex, uint32 InNetId, uint32 InBitOffset, uint32 InBitSize, uint32 InLevel) : EventTypeIndex(InEventTypeIndex), ObjectInstanceIndex(InObjectInstanceIndex), NetId(InNetId), BitOffset(InBitOffset), BitSize(InBitSize), Level(InLevel) {} FNetworkPacketEvent(const FNetworkPacketEvent& Other) : EventTypeIndex(Other.EventTypeIndex), ObjectInstanceIndex(Other.ObjectInstanceIndex), NetId(Other.NetId), BitOffset(Other.BitOffset), BitSize(Other.BitSize), Level(Other.Level) { } FNetworkPacketEvent& operator=(const FNetworkPacketEvent& Other) { EventTypeIndex = Other.EventTypeIndex; ObjectInstanceIndex = Other.ObjectInstanceIndex; NetId = Other.NetId; BitOffset = Other.BitOffset; BitSize = Other.BitSize; Level = Other.Level; return *this; } bool Equals(const FNetworkPacketEvent& Other) const { return EventTypeIndex == Other.EventTypeIndex && ObjectInstanceIndex == Other.ObjectInstanceIndex && NetId == Other.NetId && BitOffset == Other.BitOffset && BitSize == Other.BitSize && Level == Other.Level; } static bool AreEquals(const FNetworkPacketEvent& A, const FNetworkPacketEvent& B) { return A.Equals(B); } }; //////////////////////////////////////////////////////////////////////////////////////////////////// struct FPacketContentViewDrawState { struct FBoxPrimitive { int32 Depth; float X; float W; FLinearColor Color; }; struct FTextPrimitive { int32 Depth; float X; FString Text; bool bWhite; }; FPacketContentViewDrawState() : Events(), Boxes(), InsideBoxes(), Borders(), Texts(), NumLanes(0), NumMergedBoxes(0) { } void Reset() { Events.Reset(); Boxes.Reset(); InsideBoxes.Reset(); Borders.Reset(); Texts.Reset(); NumLanes = 0; NumMergedBoxes = 0; } int32 GetNumLanes() const { return NumLanes; } int32 GetNumEvents() const { return Events.Num(); } int32 GetNumMergedBoxes() const { return NumMergedBoxes; } int32 GetTotalNumBoxes() const { return Boxes.Num() + InsideBoxes.Num(); } TArray Events; TArray Boxes; TArray InsideBoxes; TArray Borders; TArray Texts; int32 NumLanes; // Debug stats. int32 NumMergedBoxes; }; //////////////////////////////////////////////////////////////////////////////////////////////////// class FPacketContentViewDrawStateBuilder { private: struct FBoxData { float X1; float X2; uint32 Color; FLinearColor LinearColor; FBoxData(): X1(0.0f), X2(0.0f), Color(0) {} void Reset() { X1 = 0.0f; X2 = 0.0f; Color = 0; } }; public: explicit FPacketContentViewDrawStateBuilder(FPacketContentViewDrawState& InState, const FPacketContentViewport& InViewport); /** * Non-copyable */ FPacketContentViewDrawStateBuilder(const FPacketContentViewDrawStateBuilder&) = delete; FPacketContentViewDrawStateBuilder& operator=(const FPacketContentViewDrawStateBuilder&) = delete; void AddEvent(const Trace::FNetProfilerContentEvent& Event, const TCHAR* Name, uint32 NetId); void Flush(); int32 GetMaxDepth() const { return MaxDepth; } private: void FlushBox(const FBoxData& Box, const int32 Depth); private: FPacketContentViewDrawState& DrawState; // cached draw state to build const FPacketContentViewport& Viewport; int32 MaxDepth; TArray LastEventX2; // X2 value for last event on each depth TArray LastBox; const FSlateFontInfo EventFont; }; //////////////////////////////////////////////////////////////////////////////////////////////////// class FPacketContentViewDrawHelper { public: enum class EHighlightMode : uint32 { Hovered = 1, Selected = 2, SelectedAndHovered = 3 }; public: explicit FPacketContentViewDrawHelper(const FDrawContext& InDrawContext, const FPacketContentViewport& InViewport); /** * Non-copyable */ FPacketContentViewDrawHelper(const FPacketContentViewDrawHelper&) = delete; FPacketContentViewDrawHelper& operator=(const FPacketContentViewDrawHelper&) = delete; const FSlateBrush* GetWhiteBrush() const { return WhiteBrush; } const FSlateFontInfo& GetEventFont() const { return EventFont; } float GetLayoutPosY() const { return LayoutPosY; } float GetLayoutEventH() const { return LayoutEventH; } float GetLayoutEventDY() const { return LayoutEventDY; } void SetLayoutPosY(const float InLayoutPosY) { LayoutPosY = InLayoutPosY; } void SetLayoutEventH(const float InLayoutEventH) { LayoutEventH = InLayoutEventH; } void SetLayoutEventDY(const float InLayoutEventDY) { LayoutEventDY = InLayoutEventDY; } void DrawBackground() const; void Draw(const FPacketContentViewDrawState& DrawState, const float Opacity = 1.0f) const; void DrawEventHighlight(const FNetworkPacketEvent& Event, EHighlightMode Mode) const; static FLinearColor GetColorByType(int32 Type); private: const FDrawContext& DrawContext; const FPacketContentViewport& Viewport; const FSlateBrush* WhiteBrush; const FSlateBrush* EventBorderBrush; const FSlateBrush* HoveredEventBorderBrush; const FSlateBrush* SelectedEventBorderBrush; const FSlateFontInfo EventFont; float LayoutPosY; float LayoutEventH; float LayoutEventDY; }; ////////////////////////////////////////////////////////////////////////////////////////////////////