// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Trace/Config.h" #if TRACE_PRIVATE_MINIMAL_ENABLED #include "Atomic.h" #include "Protocol.h" #include "Templates/UnrealTemplate.h" #include "Trace/Trace.h" #include "Writer.inl" /* Statically sized fields (e.g. UE_TRACE_EVENT_FIELD(float[4], Colours)) are * not supported as yet. No call for them. The following define is used to track * where and partially how to implement them */ #define STATICALLY_SIZED_ARRAY_FIELDS_SUPPORT 0 namespace UE { namespace Trace { namespace Private { //////////////////////////////////////////////////////////////////////////////// UE_TRACE_API void Field_WriteAuxData(uint32, const uint8*, int32); UE_TRACE_API void Field_WriteStringAnsi(uint32, const ANSICHAR*, int32); UE_TRACE_API void Field_WriteStringAnsi(uint32, const WIDECHAR*, int32); UE_TRACE_API void Field_WriteStringWide(uint32, const WIDECHAR*, int32); class FEventNode; } // namespace Private //////////////////////////////////////////////////////////////////////////////// enum DisabledField {}; template struct TFieldType; template <> struct TFieldType{ enum { Tid = 0, Size = 0 }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Bool), Size = sizeof(bool) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Int8), Size = sizeof(int8) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Int16), Size = sizeof(int16) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Int32), Size = sizeof(int32) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Int64), Size = sizeof(int64) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Uint8), Size = sizeof(uint8) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Uint16), Size = sizeof(uint16) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Uint32), Size = sizeof(uint32) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Uint64), Size = sizeof(uint64) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Float32),Size = sizeof(float) }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::Float64),Size = sizeof(double) }; }; template struct TFieldType { enum { Tid = int(EFieldType::Pointer),Size = sizeof(void*) }; }; template struct TFieldType { enum { Tid = int(TFieldType::Tid)|int(EFieldType::Array), Size = 0, }; }; #if STATICALLY_SIZED_ARRAY_FIELDS_SUPPORT template struct TFieldType { enum { Tid = int(TFieldType::Tid)|int(EFieldType::Array), Size = sizeof(T[N]), }; }; #endif // STATICALLY_SIZED_ARRAY_FIELDS_SUPPORT template <> struct TFieldType { enum { Tid = int(EFieldType::AnsiString), Size = 0, }; }; template <> struct TFieldType { enum { Tid = int(EFieldType::WideString), Size = 0, }; }; //////////////////////////////////////////////////////////////////////////////// struct FLiteralName { template explicit FLiteralName(const ANSICHAR (&Name)[Size]) : Ptr(Name) , Length(Size - 1) { static_assert(Size < 256, "Field name is too large"); } const ANSICHAR* Ptr; uint8 Length; }; //////////////////////////////////////////////////////////////////////////////// struct FFieldDesc { FFieldDesc(const FLiteralName& Name, uint8 Type, uint16 Offset, uint16 Size, uint32 ReferencedUid = 0) : Name(Name.Ptr) , ValueOffset(Offset) , ValueSize(Size) , NameSize(Name.Length) , TypeInfo(Type) , Reference(ReferencedUid) { } const ANSICHAR* Name; uint16 ValueOffset; uint16 ValueSize; uint8 NameSize; uint8 TypeInfo; uint32 Reference; }; //////////////////////////////////////////////////////////////////////////////// template struct TField; enum class EIndexPack { NumFieldsMax = 1 << FAuxHeader::FieldBits, NumFieldsShift = 8, NumFieldsMask = (1 << NumFieldsShift) - 1, AuxFieldCounter = 1 << NumFieldsShift, }; //////////////////////////////////////////////////////////////////////////////// #define TRACE_PRIVATE_FIELD(InIndex, InOffset, Type) \ enum \ { \ Index = InIndex, \ Offset = InOffset, \ Tid = TFieldType::Tid, \ Size = TFieldType::Size, \ }; \ static_assert((Index & int(EIndexPack::NumFieldsMask)) < int(EIndexPack::NumFieldsMax), "Trace events may only have up to EIndexPack::NumFieldsMax fields"); \ private: \ FFieldDesc FieldDesc; \ public: \ TField(const FLiteralName& Name) \ : FieldDesc(Name, Tid, Offset, Size) \ { \ } //////////////////////////////////////////////////////////////////////////////// template struct TField { TRACE_PRIVATE_FIELD(InIndex + int(EIndexPack::AuxFieldCounter), InOffset, Type[]); }; #if STATICALLY_SIZED_ARRAY_FIELDS_SUPPORT //////////////////////////////////////////////////////////////////////////////// template struct TField { TRACE_PRIVATE_FIELD(InIndex, InOffset, Type[Count]); }; #endif // STATICALLY_SIZED_ARRAY_FIELDS_SUPPORT //////////////////////////////////////////////////////////////////////////////// template struct TField { TRACE_PRIVATE_FIELD(InIndex + int(EIndexPack::AuxFieldCounter), InOffset, AnsiString); }; //////////////////////////////////////////////////////////////////////////////// template struct TField { TRACE_PRIVATE_FIELD(InIndex + int(EIndexPack::AuxFieldCounter), InOffset, WideString); }; //////////////////////////////////////////////////////////////////////////////// template struct TField> { TRACE_PRIVATE_FIELD(InIndex, InOffset, DefinitionType); public: TField(const FLiteralName& Name, uint32 ReferencedUid) : FieldDesc(Name, Tid, Offset, Size, ReferencedUid) { } }; //////////////////////////////////////////////////////////////////////////////// template struct TField { TRACE_PRIVATE_FIELD(InIndex, InOffset, Type); }; #undef TRACE_PRIVATE_FIELD //////////////////////////////////////////////////////////////////////////////// // Used to terminate the field list and determine an event's size. enum EventProps {}; template struct TField { enum : uint16 { NumFields = InNumFields & int(EIndexPack::NumFieldsMask), Size = InSize, NumAuxFields = (InNumFields >> int(EIndexPack::NumFieldsShift)) & int(EIndexPack::NumFieldsMask), }; }; } // namespace Trace } // namespace UE #endif // TRACE_PRIVATE_MINIMAL_ENABLED