Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,137 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Debug/Trace.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Memory/OSAllocator.h>
#if defined(AZ_ENABLE_TRACING)
# define AZ_ENABLE_TRACE_CONTEXT
#endif
#ifdef AZ_ENABLE_TRACE_CONTEXT
#include <AzCore/Preprocessor/Sequences.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/osstring.h>
#include <AzCore/Math/Uuid.h>
namespace AzToolsFramework
{
namespace Debug
{
// TraceContext provides access to a per-thread stack that can keep track of simple
// scoped key-value pairs. Entries are scoped and will automatically be removed once they go
// out of scope. The information gathered through this EBus can be used to provide additional
// information for logging that's collected over multiple function calls. This largely eliminates
// the need to pass context information as parameters to functions or to collect return values to
// reconstruct the context. As this information is available when logging warnings or errors, it
// also helps reduce the amount of log spam.
// Several default implementations are provided for handling, recording and formatting the stack
// constructed via this EBus, such as the TraceContextStack, TraceContextSingleStackHandler and
// the TraceContextLogFormatter.
//
// Usage example:
// const char* gameFolder = m_context.pRC->GetSystemEnvironment()->pFileIO->GetAlias("@devassets@");
// AZ_TraceContext("Game folder", gameFolder);
//
// for (int i=0; i<subMeshCount; ++i)
// {
// AZ_TraceContext("Current mesh", i);
// ...
//
// AZ_TraceContext("Scale", 1.5f);
//
// AZ_TraceContext("Merging enabled", true);
//
// AZ::Uuid tag = AZ::Uuid::CreateRandom();
// AZ_TraceContext("Mesh Processing Tag", tag);
class TraceContext : public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
using AllocatorType = AZ::OSStdAllocator;
virtual void PushStringEntry(AZStd::thread::id threadId, const char* key, const char* value) = 0;
virtual void PushBoolEntry(AZStd::thread::id threadId, const char* key, bool value) = 0;
virtual void PushIntEntry(AZStd::thread::id threadId, const char* key, int64_t value) = 0;
virtual void PushUintEntry(AZStd::thread::id threadId, const char* key, uint64_t value) = 0;
virtual void PushFloatEntry(AZStd::thread::id threadId, const char* key, float value) = 0;
virtual void PushDoubleEntry(AZStd::thread::id threadId, const char* key, double value) = 0;
virtual void PushUuidEntry(AZStd::thread::id threadId, const char* key, const AZ::Uuid* value) = 0;
virtual void PopEntry(AZStd::thread::id threadId) = 0;
};
using TraceContextBus = AZ::EBus<TraceContext>;
class TraceContextScope
{
public:
inline TraceContextScope(const char* key, const char* value);
inline TraceContextScope(const char* key, const AZStd::string& value);
inline TraceContextScope(const char* key, const AZ::OSString& value);
inline TraceContextScope(const char* key, bool value);
inline TraceContextScope(const char* key, int8_t value);
inline TraceContextScope(const char* key, int16_t value);
inline TraceContextScope(const char* key, int32_t value);
inline TraceContextScope(const char* key, int64_t value);
inline TraceContextScope(const char* key, uint8_t value);
inline TraceContextScope(const char* key, uint16_t value);
inline TraceContextScope(const char* key, uint32_t value);
inline TraceContextScope(const char* key, uint64_t value);
inline TraceContextScope(const char* key, float value);
inline TraceContextScope(const char* key, double value);
inline TraceContextScope(const char* key, const AZ::Uuid& value);
inline TraceContextScope(const char* key, const AZ::Uuid* value);
inline TraceContextScope(const AZStd::string& key, const char* value);
inline TraceContextScope(const AZStd::string& key, const AZStd::string& value);
inline TraceContextScope(const AZStd::string& key, const AZ::OSString& value);
inline TraceContextScope(const AZStd::string& key, bool value);
inline TraceContextScope(const AZStd::string& key, int8_t value);
inline TraceContextScope(const AZStd::string& key, int16_t value);
inline TraceContextScope(const AZStd::string& key, int32_t value);
inline TraceContextScope(const AZStd::string& key, int64_t value);
inline TraceContextScope(const AZStd::string& key, uint8_t value);
inline TraceContextScope(const AZStd::string& key, uint16_t value);
inline TraceContextScope(const AZStd::string& key, uint32_t value);
inline TraceContextScope(const AZStd::string& key, uint64_t value);
inline TraceContextScope(const AZStd::string& key, float value);
inline TraceContextScope(const AZStd::string& key, double value);
inline TraceContextScope(const AZStd::string& key, const AZ::Uuid& value);
inline TraceContextScope(const AZStd::string& key, const AZ::Uuid* value);
inline ~TraceContextScope();
};
} // Debug
} // AzToolsFramework
#define AZ_TraceContext(key, value) AzToolsFramework::Debug::TraceContextScope AZ_SEQ_JOIN(traceContextScope, __COUNTER__) (key, value)
#include <AzToolsFramework/Debug/TraceContext.inl>
#else // AZ_ENABLE_TRACE_CONTEXT
class TraceContext : public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
using AllocatorType = AZ::OSStdAllocator;
};
using TraceContextBus = AZ::EBus<TraceContext>;
#define AZ_TraceContext(key, value) do { (void)key; (void)value; } while(false)
#endif // AZ_ENABLE_TRACE_CONTEXT
@@ -0,0 +1,186 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifdef AZ_ENABLE_TRACE_CONTEXT
namespace AzToolsFramework
{
namespace Debug
{
TraceContextScope::TraceContextScope(const char* key, const char* value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key , value);
}
TraceContextScope::TraceContextScope(const char* key, const AZStd::string& value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key , value.c_str());
}
TraceContextScope::TraceContextScope(const char* key, const AZ::OSString& value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key, value.c_str());
}
TraceContextScope::TraceContextScope(const char* key, bool value)
{
EBUS_EVENT(TraceContextBus, PushBoolEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, int8_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, int16_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, int32_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, int64_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, uint8_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, uint16_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, uint32_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, uint64_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, float value)
{
EBUS_EVENT(TraceContextBus, PushFloatEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, double value)
{
EBUS_EVENT(TraceContextBus, PushDoubleEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const char* key, const AZ::Uuid& value)
{
EBUS_EVENT(TraceContextBus, PushUuidEntry, AZStd::this_thread::get_id(), key, &value);
}
TraceContextScope::TraceContextScope(const char* key, const AZ::Uuid* value)
{
EBUS_EVENT(TraceContextBus, PushUuidEntry, AZStd::this_thread::get_id(), key, value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, const char* value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, const AZStd::string& value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key.c_str(), value.c_str());
}
TraceContextScope::TraceContextScope(const AZStd::string& key, const AZ::OSString& value)
{
EBUS_EVENT(TraceContextBus, PushStringEntry, AZStd::this_thread::get_id(), key.c_str(), value.c_str());
}
TraceContextScope::TraceContextScope(const AZStd::string& key, bool value)
{
EBUS_EVENT(TraceContextBus, PushBoolEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, int8_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, int16_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, int32_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, int64_t value)
{
EBUS_EVENT(TraceContextBus, PushIntEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, uint8_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, uint16_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, uint32_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, uint64_t value)
{
EBUS_EVENT(TraceContextBus, PushUintEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, float value)
{
EBUS_EVENT(TraceContextBus, PushFloatEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, double value)
{
EBUS_EVENT(TraceContextBus, PushDoubleEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, const AZ::Uuid& value)
{
EBUS_EVENT(TraceContextBus, PushUuidEntry, AZStd::this_thread::get_id(), key.c_str(), &value);
}
TraceContextScope::TraceContextScope(const AZStd::string& key, const AZ::Uuid* value)
{
EBUS_EVENT(TraceContextBus, PushUuidEntry, AZStd::this_thread::get_id(), key.c_str(), value);
}
TraceContextScope::~TraceContextScope()
{
EBUS_EVENT(TraceContextBus, PopEntry, AZStd::this_thread::get_id());
}
} // Debug
} // AzToolsFramework
#endif // AZ_ENABLE_TRACE_CONTEXT
@@ -0,0 +1,153 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzToolsFramework/Debug/TraceContextBufferedFormatter.h>
#ifdef AZ_ENABLE_TRACE_CONTEXT
#include <AzCore/Math/Uuid.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzToolsFramework/Debug/TraceContextStackInterface.h>
#include <inttypes.h>
#endif // AZ_ENABLE_TRACE_CONTEXT
namespace AzToolsFramework
{
namespace Debug
{
#ifdef AZ_ENABLE_TRACE_CONTEXT
int TraceContextBufferedFormatter::Print(char* buffer, size_t bufferSize, const TraceContextStackInterface& stack, bool printUuids, size_t startIndex)
{
if (bufferSize == 0)
{
return -1;
}
// Make sure there's always a terminator, even if nothing has been written.
buffer[0] = 0;
size_t stackSize = stack.GetStackCount();
for (size_t i = startIndex; i < stackSize; ++i)
{
int written = 0;
switch (stack.GetType(i))
{
case TraceContextStackInterface::ContentType::StringType:
written = azsnprintf(buffer, bufferSize, "%s=%s\n", stack.GetKey(i), stack.GetStringValue(i));
break;
case TraceContextStackInterface::ContentType::BoolType:
written = azsnprintf(buffer, bufferSize, "%s=%c\n", stack.GetKey(i), (stack.GetBoolValue(i) ? '1' : '0'));
break;
case TraceContextStackInterface::ContentType::IntType:
written = azsnprintf(buffer, bufferSize, "%s=%" PRIi64 "\n", stack.GetKey(i), stack.GetIntValue(i));
break;
case TraceContextStackInterface::ContentType::UintType:
written = azsnprintf(buffer, bufferSize, "%s=%" PRIu64 "\n", stack.GetKey(i), stack.GetUIntValue(i));
break;
case TraceContextStackInterface::ContentType::FloatType:
written = azsnprintf(buffer, bufferSize, "%s=%f\n", stack.GetKey(i), stack.GetFloatValue(i));
break;
case TraceContextStackInterface::ContentType::DoubleType:
written = azsnprintf(buffer, bufferSize, "%s=%f\n", stack.GetKey(i), stack.GetDoubleValue(i));
break;
case TraceContextStackInterface::ContentType::UuidType:
if (printUuids)
{
written = azsnprintf(buffer, bufferSize, "%s=", stack.GetKey(i));
if (written > 0)
{
int uuidWritten = PrintUuid(buffer + written, bufferSize - written, stack.GetUuidValue(i));
written = (uuidWritten < 0 ? -1 : (written + uuidWritten));
}
break;
}
else
{
continue;
}
case TraceContextStackInterface::ContentType::Undefined:
written = azsnprintf(buffer, bufferSize, "<UNDEFINED>\n");
break;
default:
written = azsnprintf(buffer, bufferSize, "<UNKNOWN>\n");
break;
}
// If successful azsnprintf will return the number of characters that were
// written, so move the buffer forward and reduce the available space.
// Otherwise see if there's anything written that needs to be recovered
// or to simply move to the next entry upon re-entry.
if (written > 0)
{
buffer += written;
bufferSize -= written;
}
else
{
// If the startIndex is the same as the current index, this is the first
// entry to be written. It means this is the largest the buffer will
// ever get, so leave whatever has been written in place. Do however
// add a newline.
if (startIndex == i)
{
if (bufferSize >= 2)
{
buffer[bufferSize - 2] = '\n';
buffer[bufferSize - 1] = 0;
}
return aznumeric_caster(i + 1);
}
else
{
if (bufferSize > 0)
{
// Remove whatever part has been written as it's not complete.
*buffer = 0;
}
}
return aznumeric_caster(i);
}
}
return -1;
}
int TraceContextBufferedFormatter::PrintUuid(char* buffer, size_t bufferSize, const AZ::Uuid& uuid)
{
int written = uuid.ToString(buffer, aznumeric_caster(bufferSize), false);
if (written > 0)
{
if (bufferSize - written > 0)
{
buffer[written - 1] = '\n';
buffer[written] = 0;
return written + 1;
}
}
return -1;
}
#else // AZ_ENABLE_TRACE_CONTEXT
int TraceContextBufferedFormatter::Print(char* /*buffer*/, size_t /*bufferSize*/,
const TraceContextStackInterface& /*stack*/, bool /*printUuids*/, size_t /*startIndex*/)
{
return -1;
}
#endif // AZ_ENABLE_TRACE_CONTEXT
} // Debug
} // AzToolsFramework
@@ -0,0 +1,70 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/base.h>
namespace AZ
{
struct Uuid;
}
namespace AzToolsFramework
{
namespace Debug
{
class TraceContextStackInterface;
// TraceContexBufferedFormatter takes a trace context stack and prints it to the given buffer.
// It's aimed to be used with small to micro sized character buffers. (At least 50-100
// characters is advised.) If the entire context couldn't be written to the buffer, Build
// can be called repeatedly with the returned index to continue printing the buffer. If a
// single context entry doesn't fit in the buffer, TraceContexBufferedFormatter will attempt
// to write as much data as can be fitted in the buffer.
//
// Typical usage looks like:
// TraceContextSingleStackHandler stackHandler;
// ...
// TraceContexBufferedFormatter buffered;
// char buffer[64];
// int index = 0;
// do
// {
// index = buffered.Build(buffer, stackHandler.GetStack(), true, index);
// Print(buffer);
// } while (index >= 0);
//
// Example output:
// String=text
// Integer=42
// Float=3.141500
// Uuid=E2C7EEFA-B1CA-465F-A4BC-30514F76B7B5
class TraceContextBufferedFormatter
{
public:
// Prints the trace context to the given buffer, tags.
// If printUuids is true, the uuid of objects and tags is printed as well.
// Use startIndex to continue from a specific entry.
// Returns the index of the next entry to be written or -1 if no entries are left.
static int Print(char* buffer, size_t bufferSize, const TraceContextStackInterface& stack, bool printUuids, size_t startIndex = 0);
template<size_t size>
static inline int Print(char(&buffer)[size], const TraceContextStackInterface& stack, bool printUuids, size_t startIndex = 0);
private:
static int PrintUuid(char* buffer, size_t bufferSize, const AZ::Uuid& uuid);
};
} // Debug
} // AzToolsFramework
#include <AzToolsFramework/Debug/TraceContextBufferedFormatter.inl>
@@ -0,0 +1,23 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
namespace AzToolsFramework
{
namespace Debug
{
template<size_t size>
inline int TraceContextBufferedFormatter::Print(char(&buffer)[size], const TraceContextStackInterface& stack, bool printUuids, size_t startIndex)
{
return Print(buffer, size, stack, printUuids, startIndex);
}
} // Debug
} // AzToolsFramework
@@ -0,0 +1,113 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzToolsFramework/Debug/TraceContextLogFormatter.h>
#ifdef AZ_ENABLE_TRACE_CONTEXT
#include <AzToolsFramework/Debug/TraceContextStackInterface.h>
#endif // AZ_ENABLE_TRACE_CONTEXT
#include <cinttypes>
namespace AzToolsFramework
{
namespace Debug
{
#ifdef AZ_ENABLE_TRACE_CONTEXT
void TraceContextLogFormatter::Print(AZStd::string& out, const TraceContextStackInterface& stack, bool printUuids)
{
size_t stackSize = stack.GetStackCount();
for (size_t i = 0; i < stackSize; ++i)
{
if (!printUuids && stack.GetType(i) == TraceContextStackInterface::ContentType::UuidType)
{
continue;
}
PrintLine(out, stack, i);
out += '\n';
}
}
void TraceContextLogFormatter::PrintLine(AZStd::string& out, const TraceContextStackInterface& stack, size_t index)
{
// Don't assert on this as it could cause an infinite loop of asserts that trigger trace context reporting.
if (index >= stack.GetStackCount())
{
return;
}
out += AZStd::string::format("[%s] = ", stack.GetKey(index));
PrintValue(out, stack, index);
}
void TraceContextLogFormatter::PrintValue(AZStd::string& out, const TraceContextStackInterface& stack, size_t index)
{
// Don't assert on this as it could cause an infinite loop of asserts that trigger trace context reporting.
if (index >= stack.GetStackCount())
{
return;
}
switch (stack.GetType(index))
{
case TraceContextStackInterface::ContentType::StringType:
out += stack.GetStringValue(index);
break;
case TraceContextStackInterface::ContentType::BoolType:
out += stack.GetBoolValue(index) ? "true" : "false";
break;
case TraceContextStackInterface::ContentType::IntType:
out += AZStd::string::format("%" PRId64, stack.GetIntValue(index));
break;
case TraceContextStackInterface::ContentType::UintType:
out += AZStd::string::format("%" PRIu64, stack.GetUIntValue(index));
break;
case TraceContextStackInterface::ContentType::FloatType:
out += AZStd::string::format("%f", stack.GetFloatValue(index));
break;
case TraceContextStackInterface::ContentType::DoubleType:
out += AZStd::string::format("%f", stack.GetDoubleValue(index));
break;
case TraceContextStackInterface::ContentType::UuidType:
out += stack.GetUuidValue(index).ToString<AZStd::string>(false).c_str();
break;
case TraceContextStackInterface::ContentType::Undefined:
out += "<undefined value type>";
break;
default:
out += "<unknown value type>";
break;
}
}
#else // AZ_ENABLE_TRACE_CONTEXT
void TraceContextLogFormatter::Print(AZStd::string& /*out*/, const TraceContextStackInterface& /*stack*/, bool /*printUuids*/)
{
}
void TraceContextLogFormatter::PrintLine(AZStd::string& /*out*/, const TraceContextStackInterface& /*stack*/, size_t /*index*/)
{
}
void TraceContextLogFormatter::PrintValue(AZStd::string& /*out*/, const TraceContextStackInterface& /*stack*/, size_t /*index*/)
{
}
#endif // AZ_ENABLE_TRACE_CONTEXT
} // Debug
} // AzToolsFramework
@@ -0,0 +1,49 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/ObjectStream.h>
namespace AZ
{
struct Uuid;
}
namespace AzToolsFramework
{
namespace Debug
{
class TraceContextStackInterface;
// TraceContextLogFormatter takes the trace context for the current thread and prints
// it to a string. It's aimed to create a humanly readable output to provide
// contextual information alongside a message. By default uuids are ignored, but
// optionally these can be printed as well.
//
// Typical output will look like:
// [String] = text
// [Integer] = 42
// [Float] = 3.141500
// [Uuid] = B0E342BA-0D79-412D-ABDE-11FC29D4875C
class TraceContextLogFormatter
{
public:
// Prints all entries in the trace context stack to a string, except any object or tags.
static void Print(AZStd::string& out, const TraceContextStackInterface& stack, bool printUuids = false);
// Appends a single entry from the trace context stack to a string.
static void PrintLine(AZStd::string& out, const TraceContextStackInterface& stack, size_t index);
// Appends a single value from the trace context stack to a string.
static void PrintValue(AZStd::string& out, const TraceContextStackInterface& stack, size_t index);
};
} // Debug
} // AzToolsFramework
@@ -0,0 +1,166 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContextMultiStackHandler.h>
namespace AzToolsFramework
{
namespace Debug
{
#ifdef AZ_ENABLE_TRACE_CONTEXT
TraceContextMultiStackHandler::TraceContextMultiStackHandler()
{
BusConnect();
}
TraceContextMultiStackHandler::~TraceContextMultiStackHandler()
{
BusDisconnect();
}
void TraceContextMultiStackHandler::PushStringEntry(AZStd::thread::id threadId, const char* key, const char* value)
{
GetStackByThreadId(threadId).PushStringEntry(key, value);
}
void TraceContextMultiStackHandler::PushBoolEntry(AZStd::thread::id threadId, const char* key, bool value)
{
GetStackByThreadId(threadId).PushBoolEntry(key, value);
}
void TraceContextMultiStackHandler::PushIntEntry(AZStd::thread::id threadId, const char* key, int64_t value)
{
GetStackByThreadId(threadId).PushIntEntry(key, value);
}
void TraceContextMultiStackHandler::PushUintEntry(AZStd::thread::id threadId, const char* key, uint64_t value)
{
GetStackByThreadId(threadId).PushUintEntry(key, value);
}
void TraceContextMultiStackHandler::PushFloatEntry(AZStd::thread::id threadId, const char* key, float value)
{
GetStackByThreadId(threadId).PushFloatEntry(key, value);
}
void TraceContextMultiStackHandler::PushDoubleEntry(AZStd::thread::id threadId, const char* key, double value)
{
GetStackByThreadId(threadId).PushDoubleEntry(key, value);
}
void TraceContextMultiStackHandler::PushUuidEntry(AZStd::thread::id threadId, const char* key, const AZ::Uuid* value)
{
GetStackByThreadId(threadId).PushUuidEntry(key, value);
}
void TraceContextMultiStackHandler::PopEntry(AZStd::thread::id threadId)
{
GetStackByThreadId(threadId).PopEntry();
}
size_t TraceContextMultiStackHandler::GetStackCount() const
{
return m_threadStacks.size();
}
uint64_t TraceContextMultiStackHandler::GetStackId(size_t index) const
{
if (index < m_threadStacks.size())
{
auto iterator = m_threadStacks.begin();
AZStd::advance(iterator, index);
return iterator->first;
}
else
{
return 0;
}
}
AZStd::shared_ptr<const TraceContextStack> TraceContextMultiStackHandler::GetStack(size_t index) const
{
if (index < m_threadStacks.size())
{
auto iterator = m_threadStacks.begin();
AZStd::advance(iterator, index);
return iterator->second;
}
else
{
return nullptr;
}
}
AZStd::shared_ptr<const TraceContextStack> TraceContextMultiStackHandler::GetCurrentStack() const
{
uint64_t currentThreadId = (uint64_t)AZStd::this_thread::get_id().m_id;
auto entry = m_threadStacks.find(currentThreadId);
if (entry != m_threadStacks.end())
{
return entry->second;
}
else
{
return nullptr;
}
}
TraceContextStack& TraceContextMultiStackHandler::GetStackByThreadId(AZStd::thread::id threadId)
{
// Using a c-style cast because AZStd::hash hasn't been specialized (yet) for thread::id and the type can differ per
// platform, requiring static_cast on some and reinterpret_cast on others;
auto entry = m_threadStacks.find((uint64_t)threadId.m_id);
if (entry != m_threadStacks.end())
{
return *(entry->second);
}
else
{
AZStd::shared_ptr<TraceContextStack> traceContext = AZStd::make_shared<TraceContextStack>();
m_threadStacks[(uint64_t)threadId.m_id] = traceContext;
return *traceContext;
}
}
#else // AZ_ENABLE_TRACE_CONTEXT
TraceContextMultiStackHandler::TraceContextMultiStackHandler()
{
}
TraceContextMultiStackHandler::~TraceContextMultiStackHandler()
{
}
size_t TraceContextMultiStackHandler::GetStackCount() const
{
return 0;
}
uint64_t TraceContextMultiStackHandler::GetStackId(size_t /*index*/) const
{
return 0;
}
AZStd::shared_ptr<const TraceContextStack> TraceContextMultiStackHandler::GetStack(size_t /*index*/) const
{
return nullptr;
}
AZStd::shared_ptr<const TraceContextStack> TraceContextMultiStackHandler::GetCurrentStack() const
{
return nullptr;
}
#endif // AZ_ENABLE_TRACE_CONTEXT
} // Debug
} // AzToolsFramework
@@ -0,0 +1,57 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzToolsFramework/Debug/TraceContextStack.h>
namespace AzToolsFramework
{
namespace Debug
{
// TraceContextMultiStack provides a standard implementation for the TraceContextBus that
// can be used for tracking trace context stacks for multiple threads.
class TraceContextMultiStackHandler : public TraceContextBus::Handler
{
public:
TraceContextMultiStackHandler();
~TraceContextMultiStackHandler() override;
#ifdef AZ_ENABLE_TRACE_CONTEXT
void PushStringEntry(AZStd::thread::id threadId, const char* key, const char* value) override;
void PushBoolEntry(AZStd::thread::id threadId, const char* key, bool value) override;
void PushIntEntry(AZStd::thread::id threadId, const char* key, int64_t value) override;
void PushUintEntry(AZStd::thread::id threadId, const char* key, uint64_t value) override;
void PushFloatEntry(AZStd::thread::id threadId, const char* key, float value) override;
void PushDoubleEntry(AZStd::thread::id threadId, const char* key, double value) override;
void PushUuidEntry(AZStd::thread::id threadId, const char* key, const AZ::Uuid* value) override;
void PopEntry(AZStd::thread::id threadId) override;
#endif // AZ_ENABLE_TRACE_CONTEXT
virtual size_t GetStackCount() const;
virtual uint64_t GetStackId(size_t index) const;
virtual AZStd::shared_ptr<const TraceContextStack> GetStack(size_t index) const;
// Returns the stack for the current stack if available, otherwise null.
virtual AZStd::shared_ptr<const TraceContextStack> GetCurrentStack() const;
protected:
#ifdef AZ_ENABLE_TRACE_CONTEXT
virtual TraceContextStack& GetStackByThreadId(AZStd::thread::id threadId);
#endif
AZStd::unordered_map<uint64_t, AZStd::shared_ptr<TraceContextStack>> m_threadStacks;
};
} // Debug
} // AzToolsFramework
@@ -0,0 +1,127 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzToolsFramework/Debug/TraceContextSingleStackHandler.h>
namespace AzToolsFramework
{
namespace Debug
{
#ifdef AZ_ENABLE_TRACE_CONTEXT
TraceContextSingleStackHandler::TraceContextSingleStackHandler()
: m_targetThread(AZStd::this_thread::get_id())
{
BusConnect();
}
TraceContextSingleStackHandler::TraceContextSingleStackHandler(AZStd::thread::id targetThread)
: m_targetThread(targetThread)
{
BusConnect();
}
TraceContextSingleStackHandler::~TraceContextSingleStackHandler()
{
BusDisconnect();
}
void TraceContextSingleStackHandler::PushStringEntry(AZStd::thread::id threadId, const char* key, const char* value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushStringEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushBoolEntry(AZStd::thread::id threadId, const char* key, bool value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushBoolEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushIntEntry(AZStd::thread::id threadId, const char* key, int64_t value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushIntEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushUintEntry(AZStd::thread::id threadId, const char* key, uint64_t value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushUintEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushFloatEntry(AZStd::thread::id threadId, const char* key, float value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushFloatEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushDoubleEntry(AZStd::thread::id threadId, const char* key, double value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushDoubleEntry(key, value);
}
}
void TraceContextSingleStackHandler::PushUuidEntry(AZStd::thread::id threadId, const char* key, const AZ::Uuid* value)
{
if (threadId == m_targetThread)
{
m_threadStack.PushUuidEntry(key, value);
}
}
void TraceContextSingleStackHandler::PopEntry(AZStd::thread::id threadId)
{
if (threadId == m_targetThread)
{
m_threadStack.PopEntry();
}
}
#else // AZ_ENABLE_TRACE_CONTEXT
TraceContextSingleStackHandler::TraceContextSingleStackHandler()
{
}
TraceContextSingleStackHandler::TraceContextSingleStackHandler(AZStd::thread::id /*targetThread*/)
{
}
TraceContextSingleStackHandler::~TraceContextSingleStackHandler()
{
}
#endif // AZ_ENABLE_TRACE_CONTEXT
AZStd::thread::id TraceContextSingleStackHandler::GetStackThreadId() const
{
return m_targetThread;
}
const TraceContextStack& TraceContextSingleStackHandler::GetStack() const
{
return m_threadStack;
}
} // Debug
} // AzToolsFramework
@@ -0,0 +1,52 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/parallel/thread.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzToolsFramework/Debug/TraceContextStack.h>
namespace AzToolsFramework
{
namespace Debug
{
// TraceContextStack provides a standard implementation for the TraceContextBus that
// can be used to track the trace context for a specific thread.
class TraceContextSingleStackHandler : public TraceContextBus::Handler
{
public:
// Sets up trace context recording for the current thread.
TraceContextSingleStackHandler();
explicit TraceContextSingleStackHandler(AZStd::thread::id targetThread);
~TraceContextSingleStackHandler() override;
#ifdef AZ_ENABLE_TRACE_CONTEXT
void PushStringEntry(AZStd::thread::id threadId, const char* key, const char* value) override;
void PushBoolEntry(AZStd::thread::id threadId, const char* key, bool value) override;
void PushIntEntry(AZStd::thread::id threadId, const char* key, int64_t value) override;
void PushUintEntry(AZStd::thread::id threadId, const char* key, uint64_t value) override;
void PushFloatEntry(AZStd::thread::id threadId, const char* key, float value) override;
void PushDoubleEntry(AZStd::thread::id threadId, const char* key, double value) override;
void PushUuidEntry(AZStd::thread::id threadId, const char* key, const AZ::Uuid* value) override;
void PopEntry(AZStd::thread::id threadId) override;
#endif // AZ_ENABLE_TRACE_CONTEXT
virtual AZStd::thread::id GetStackThreadId() const;
virtual const TraceContextStack& GetStack() const;
protected:
TraceContextStack m_threadStack;
AZStd::thread::id m_targetThread;
};
} // Debug
} // AzToolsFramework
@@ -0,0 +1,288 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Math/Uuid.h>
#include <AzToolsFramework/Debug/TraceContext.h> // Included for the AZ_ENABLE_TRACE_CONTEXT definition.
#include <AzToolsFramework/Debug/TraceContextStack.h>
namespace AzToolsFramework
{
namespace Debug
{
TraceContextStack::EntryInfo::EntryInfo(EntryInfo&& rhs)
: m_key(AZStd::move(rhs.m_key))
, m_type(rhs.m_type)
, m_value(rhs.m_value)
{
}
TraceContextStack::EntryInfo& TraceContextStack::EntryInfo::operator=(EntryInfo&& rhs)
{
m_key = AZStd::move(rhs.m_key);
m_type = rhs.m_type;
m_value = rhs.m_value;
return *this;
}
#ifdef AZ_ENABLE_TRACE_CONTEXT
size_t TraceContextStack::GetStackCount() const
{
return m_entries.size();
}
TraceContextStackInterface::ContentType TraceContextStack::GetType(size_t index) const
{
return index < m_entries.size() ? m_entries[index].m_type : ContentType::Undefined;
}
const char* TraceContextStack::GetKey(size_t index) const
{
return index < m_entries.size() ? m_entries[index].m_key.c_str() : "";
}
const char* TraceContextStack::GetStringValue(size_t index) const
{
if (IsValidRequest(index, ContentType::StringType))
{
size_t stringIndex = m_entries[index].m_value.stringValue;
if (stringIndex < m_stringStack.size())
{
return m_stringStack[stringIndex].c_str();
}
}
return "";
}
bool TraceContextStack::GetBoolValue(size_t index) const
{
return IsValidRequest(index, ContentType::BoolType) ? m_entries[index].m_value.boolValue : false;
}
int64_t TraceContextStack::GetIntValue(size_t index) const
{
return IsValidRequest(index, ContentType::IntType) ? m_entries[index].m_value.intValue : 0;
}
uint64_t TraceContextStack::GetUIntValue(size_t index) const
{
return IsValidRequest(index, ContentType::UintType) ? m_entries[index].m_value.uintValue : 0;
}
float TraceContextStack::GetFloatValue(size_t index) const
{
return IsValidRequest(index, ContentType::FloatType) ? m_entries[index].m_value.floatValue : 0.0f;
}
double TraceContextStack::GetDoubleValue(size_t index) const
{
return IsValidRequest(index, ContentType::DoubleType) ? m_entries[index].m_value.doubleValue : 0.0;
}
const AZ::Uuid& TraceContextStack::GetUuidValue(size_t index) const
{
if (IsValidRequest(index, ContentType::UuidType))
{
size_t uuidIndex = m_entries[index].m_value.uuidValue;
if (uuidIndex < m_uuidStack.size())
{
return m_uuidStack[uuidIndex];
}
}
static const AZ::Uuid nullId = AZ::Uuid::CreateNull();
return nullId;
}
bool TraceContextStack::IsValidRequest(size_t index, ContentType type) const
{
return index < m_entries.size() && type == m_entries[index].m_type;
}
void TraceContextStack::PushStringEntry(const char* key, const char* value)
{
EntryInfo entry;
entry.m_type = ContentType::StringType;
entry.m_key = key;
entry.m_value.stringValue = m_stringStack.size();
m_stringStack.emplace_back(value);
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushBoolEntry(const char* key, bool value)
{
EntryInfo entry;
entry.m_type = ContentType::BoolType;
entry.m_key = key;
entry.m_value.boolValue = value;
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushIntEntry(const char* key, int64_t value)
{
EntryInfo entry;
entry.m_type = ContentType::IntType;
entry.m_key = key;
entry.m_value.intValue = value;
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushUintEntry(const char* key, uint64_t value)
{
EntryInfo entry;
entry.m_type = ContentType::UintType;
entry.m_key = key;
entry.m_value.uintValue = value;
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushFloatEntry(const char* key, float value)
{
EntryInfo entry;
entry.m_type = ContentType::FloatType;
entry.m_key = key;
entry.m_value.floatValue = value;
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushDoubleEntry(const char* key, double value)
{
EntryInfo entry;
entry.m_type = ContentType::DoubleType;
entry.m_key = key;
entry.m_value.doubleValue = value;
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PushUuidEntry(const char* key, const AZ::Uuid* value)
{
EntryInfo entry;
entry.m_type = ContentType::UuidType;
entry.m_key = key;
entry.m_value.uuidValue = m_uuidStack.size();
m_uuidStack.push_back(value ? *value : AZ::Uuid::CreateNull());
m_entries.push_back(AZStd::move(entry));
}
void TraceContextStack::PopEntry()
{
if (m_entries.size() > 0)
{
ContentType popType = m_entries[m_entries.size() - 1].m_type;
// Some types can't be stored in unions or would make it to big. For these
// situations a separate stack is maintained and the index to the entry
// is stored in the union instead.
if (popType == ContentType::StringType)
{
if (m_stringStack.size() > 0)
{
m_stringStack.pop_back();
}
}
else if (popType == ContentType::UuidType)
{
if (m_uuidStack.size() > 0)
{
m_uuidStack.pop_back();
}
}
m_entries.pop_back();
}
}
#else // AZ_ENABLE_TRACE_CONTEXT
size_t TraceContextStack::GetStackCount() const
{
return 0;
}
TraceContextStack::ContentType TraceContextStack::GetType(size_t /*index*/) const
{
return ContentType::Undefined;
}
const char* TraceContextStack::GetKey(size_t /*index*/) const
{
return "";
}
const char* TraceContextStack::GetStringValue(size_t /*index*/) const
{
return "";
}
bool TraceContextStack::GetBoolValue(size_t /*index*/) const
{
return false;
}
int64_t TraceContextStack::GetIntValue(size_t /*index*/) const
{
return 0;
}
uint64_t TraceContextStack::GetUIntValue(size_t /*index*/) const
{
return 0;
}
float TraceContextStack::GetFloatValue(size_t /*index*/) const
{
return 0.0f;
}
double TraceContextStack::GetDoubleValue(size_t /*index*/) const
{
return 0.0;
}
const AZ::Uuid& TraceContextStack::GetUuidValue(size_t /*index*/) const
{
static const AZ::Uuid nullId = AZ::Uuid::CreateNull();
return nullId;
}
void TraceContextStack::PushStringEntry(const char* /*key*/, const char* /*value*/)
{
}
void TraceContextStack::PushBoolEntry(const char* /*key*/, bool /*value*/)
{
}
void TraceContextStack::PushIntEntry(const char* /*key*/, int64_t /*value*/)
{
}
void TraceContextStack::PushUintEntry(const char* /*key*/, uint64_t /*value*/)
{
}
void TraceContextStack::PushFloatEntry(const char* /*key*/, float /*value*/)
{
}
void TraceContextStack::PushDoubleEntry(const char* /*key*/, double /*value*/)
{
}
void TraceContextStack::PushUuidEntry(const char* /*key*/, const AZ::Uuid* /*value*/)
{
}
void TraceContextStack::PopEntry()
{
}
#endif // AZ_ENABLE_TRACE_CONTEXT
} // Debug
} // AzToolsFramework
@@ -0,0 +1,80 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string.h>
#include <AzToolsFramework/Debug/TraceContextStackInterface.h>
namespace AzToolsFramework
{
namespace Debug
{
class TraceContextStack : public TraceContextStackInterface
{
public:
~TraceContextStack() override = default;
size_t GetStackCount() const override;
ContentType GetType(size_t index) const override;
const char* GetKey(size_t index) const override;
const char* GetStringValue(size_t index) const override;
bool GetBoolValue(size_t index) const override;
int64_t GetIntValue(size_t index) const override;
uint64_t GetUIntValue(size_t index) const override;
float GetFloatValue(size_t index) const override;
double GetDoubleValue(size_t index) const override;
const AZ::Uuid& GetUuidValue(size_t index) const override;
void PushStringEntry(const char* key, const char* value);
void PushBoolEntry(const char* key, bool value);
void PushIntEntry(const char* key, int64_t value);
void PushUintEntry(const char* key, uint64_t value);
void PushFloatEntry(const char* key, float value);
void PushDoubleEntry(const char* key, double value);
void PushUuidEntry(const char* key, const AZ::Uuid* value);
void PopEntry();
protected:
inline bool IsValidRequest(size_t index, ContentType type) const;
struct EntryInfo
{
EntryInfo() = default;
EntryInfo(const EntryInfo& rhs) = default;
EntryInfo(EntryInfo&& rhs);
EntryInfo& operator=(const EntryInfo& rhs) = default;
EntryInfo& operator=(EntryInfo&& rhs);
AZStd::string m_key;
ContentType m_type;
union
{
size_t stringValue; // Index into m_stringStack
bool boolValue;
int64_t intValue;
uint64_t uintValue;
float floatValue;
double doubleValue;
size_t uuidValue; // Index into m_uuidStack
} m_value;
};
AZStd::vector<AZStd::string> m_stringStack;
AZStd::vector<AZ::Uuid> m_uuidStack;
AZStd::vector<EntryInfo> m_entries;
};
} // Debug
} // AzToolsFramework
@@ -0,0 +1,60 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <stdint.h>
#include <AzCore/PlatformDef.h>
namespace AZ
{
struct Uuid;
}
namespace AzToolsFramework
{
namespace Debug
{
class TraceContextStackInterface
{
public:
enum class ContentType
{
StringType,
BoolType,
IntType,
UintType,
FloatType,
DoubleType,
UuidType,
Undefined
};
virtual ~TraceContextStackInterface() = 0;
virtual size_t GetStackCount() const = 0;
virtual ContentType GetType(size_t index) const = 0;
virtual const char* GetKey(size_t index) const = 0;
virtual const char* GetStringValue(size_t index) const = 0;
virtual bool GetBoolValue(size_t index) const = 0;
virtual int64_t GetIntValue(size_t index) const = 0;
virtual uint64_t GetUIntValue(size_t index) const = 0;
virtual float GetFloatValue(size_t index) const = 0;
virtual double GetDoubleValue(size_t index) const = 0;
virtual const AZ::Uuid& GetUuidValue(size_t index) const = 0;
};
inline TraceContextStackInterface::~TraceContextStackInterface() = default;
} // Debug
} // AzToolsFramework