Merge remote-tracking branch 'upstream/development' into michabr/lyshine_crycommon

This commit is contained in:
abrmich
2022-01-21 10:02:28 -08:00
812 changed files with 8033 additions and 6119 deletions
@@ -191,6 +191,7 @@ void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLin
fileDialog.setViewMode(QFileDialog::List);
fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal);
fileDialog.setWindowTitle(tr("Select import destination"));
fileDialog.setFileMode(QFileDialog::Directory);
QSettings settings;
QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString();
@@ -32,6 +32,15 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserTableView);
namespace AzToolsFramework
{
namespace AssetBrowser
{
static constexpr const char* CollapseAllIcon = "Assets/Editor/Icons/AssetBrowser/Collapse_All.svg";
static constexpr const char* MenuIcon = ":/Menu/menu.svg";
} // namespace AssetBrowser
} // namespace AzToolsFramework
class ListenerForShowAssetEditorEvent
: public QObject
, private AzToolsFramework::EditorEvents::Bus::Handler
@@ -87,10 +96,21 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
m_assetBrowserModel->SetFilterModel(m_filterModel.data());
m_ui->m_collapseAllButton->setAutoRaise(true); // hover highlight
m_ui->m_collapseAllButton->setIcon(QIcon(AzAssetBrowser::CollapseAllIcon));
connect(
m_ui->m_collapseAllButton, &QToolButton::clicked, this,
[this]()
{
m_ui->m_assetBrowserTreeViewWidget->collapseAll();
});
if (ed_useNewAssetBrowserTableView)
{
m_ui->m_toggleDisplayViewBtn->setVisible(true);
m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg"));
m_ui->m_toggleDisplayViewBtn->setAutoRaise(true);
m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(AzAssetBrowser::MenuIcon));
m_tableModel->setFilterRole(Qt::DisplayRole);
m_tableModel->setSourceModel(m_filterModel.data());
@@ -72,6 +72,22 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_collapseAllButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="toolTip">
<string extracomment="Collapse All"/>
</property>
<property name="toolTipDuration">
<number>3</number>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
@@ -143,15 +159,6 @@
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
+12 -10
View File
@@ -112,29 +112,31 @@ void EditorPreferencesDialog::showEvent(QShowEvent* event)
QDialog::showEvent(event);
}
void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event)
bool WidgetConsumesKeyPressEvent(QKeyEvent* event)
{
// If the enter key is pressed during any text input, the dialog box will close
// making it inconvenient to do multiple edits. This routine captures the
// Key_Enter or Key_Return and clears the focus to give a visible cue that
// editing of that field has finished and then doesn't propogate it.
// editing of that field has finished and then doesn't propagate it.
if (event->key() != Qt::Key::Key_Enter && event->key() != Qt::Key::Key_Return)
{
QApplication::sendEvent(widget, event);
return false;
}
else
if (QWidget* editWidget = QApplication::focusWidget())
{
if (QWidget* editWidget = QApplication::focusWidget())
{
editWidget->clearFocus();
}
editWidget->clearFocus();
}
}
return true;
}
void EditorPreferencesDialog::keyPressEvent(QKeyEvent* event)
{
WidgetHandleKeyPressEvent(this, event);
if (!WidgetConsumesKeyPressEvent(event))
{
QDialog::keyPressEvent(event);
}
}
void EditorPreferencesDialog::OnTreeCurrentItemChanged()
+1 -1
View File
@@ -19,7 +19,7 @@ namespace Ui
class EditorPreferencesTreeWidgetItem;
void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event);
bool WidgetConsumesKeyPressEvent(QKeyEvent* event);
class EditorPreferencesDialog
: public QDialog
+1 -1
View File
@@ -21,7 +21,7 @@
#endif
#if defined(SANDBOX_IMPORTS) && defined(SANDBOX_EXPORTS)
#error SANDBOX_EXPORTS and SANDBOX_IMPORTS can't be defined at the same time
#error SANDBOX_EXPORTS and SANDBOX_IMPORTS cannot be defined at the same time
#endif
#if defined(SANDBOX_EXPORTS)
@@ -0,0 +1,9 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
set(LY_COMPILE_OPTIONS PRIVATE -fexceptions)
@@ -2599,11 +2599,12 @@ void OutlinerItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem&
optionV4.text.clear();
optionV4.widget->style()->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter);
// Now we setup a Text Document so it can draw the rich text
int verticalOffset = GetEntityNameVerticalOffset(entityId);
painter->translate(textRect.topLeft() + QPoint(0, verticalOffset));
AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect);
AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(
entityNameRichText, painter, optionV4, textRect, QPoint(0, verticalOffset));
painter->restore();
OutlinerListModel::s_paintingName = false;
}
-2
View File
@@ -81,8 +81,6 @@ public:
bool m_bShowStatObjects;
bool m_bShowWater;
bool m_bAutoScaleGreyRange;
friend class QTopRendererWnd;
};
#endif // CRYINCLUDE_EDITOR_TOPRENDERERWND_H
@@ -0,0 +1,478 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/DOM/DomPath.h>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/Console/ConsoleTypeHelpers.h>
namespace AZ::Dom
{
PathEntry::PathEntry(size_t value)
: m_value(value)
{
}
PathEntry::PathEntry(AZ::Name value)
: m_value(AZStd::move(value))
{
}
PathEntry::PathEntry(AZStd::string_view value)
: m_value(AZ::Name(value))
{
}
PathEntry& PathEntry::operator=(size_t value)
{
m_value = value;
return *this;
}
PathEntry& PathEntry::operator=(AZ::Name value)
{
m_value = AZStd::move(value);
return *this;
}
PathEntry& PathEntry::operator=(AZStd::string_view value)
{
m_value = AZ::Name(value);
return *this;
}
bool PathEntry::operator==(const PathEntry& other) const
{
return m_value == other.m_value;
}
bool PathEntry::operator==(size_t value) const
{
return IsIndex() && GetIndex() == value;
}
bool PathEntry::operator==(const AZ::Name& key) const
{
return IsKey() && GetKey() == key;
}
bool PathEntry::operator==(AZStd::string_view key) const
{
return IsKey() && GetKey() == AZ::Name(key);
}
bool PathEntry::operator!=(const PathEntry& other) const
{
return m_value != other.m_value;
}
bool PathEntry::operator!=(size_t value) const
{
return !IsIndex() || GetIndex() != value;
}
bool PathEntry::operator!=(const AZ::Name& key) const
{
return !IsKey() || GetKey() != key;
}
bool PathEntry::operator!=(AZStd::string_view key) const
{
return !IsKey() || GetKey() != AZ::Name(key);
}
void PathEntry::SetEndOfArray()
{
m_value = EndOfArrayIndex;
}
bool PathEntry::IsEndOfArray() const
{
const size_t* result = AZStd::get_if<size_t>(&m_value);
return result == nullptr ? false : ((*result) == EndOfArrayIndex);
}
bool PathEntry::IsIndex() const
{
const size_t* result = AZStd::get_if<size_t>(&m_value);
return result == nullptr ? false : ((*result) != EndOfArrayIndex);
}
bool PathEntry::IsKey() const
{
return AZStd::holds_alternative<AZ::Name>(m_value);
}
size_t PathEntry::GetIndex() const
{
AZ_Assert(IsIndex(), "GetIndex called on PathEntry that is not an index");
return AZStd::get<size_t>(m_value);
}
const AZ::Name& PathEntry::GetKey() const
{
AZ_Assert(IsKey(), "Key called on PathEntry that is not a key");
return AZStd::get<AZ::Name>(m_value);
}
Path::Path(AZStd::initializer_list<PathEntry> init)
: m_entries(init)
{
}
Path::Path(AZStd::string_view pathString)
{
FromString(pathString);
}
Path Path::operator/(const PathEntry& entry) const
{
Path newPath(*this);
newPath /= entry;
return newPath;
}
Path Path::operator/(size_t index) const
{
return *this / PathEntry(index);
}
Path Path::operator/(AZ::Name key) const
{
return *this / PathEntry(key);
}
Path Path::operator/(AZStd::string_view key) const
{
return *this / PathEntry(key);
}
Path Path::operator/(const Path& other) const
{
Path newPath(*this);
newPath /= other;
return newPath;
}
Path& Path::operator/=(const PathEntry& entry)
{
Push(entry);
return *this;
}
Path& Path::operator/=(size_t index)
{
return *this /= PathEntry(index);
}
Path& Path::operator/=(AZ::Name key)
{
return *this /= PathEntry(key);
}
Path& Path::operator/=(AZStd::string_view key)
{
return *this /= PathEntry(key);
}
Path& Path::operator/=(const Path& other)
{
for (const PathEntry& entry : other)
{
Push(entry);
}
return *this;
}
bool Path::operator==(const Path& other) const
{
return m_entries == other.m_entries;
}
const Path::ContainerType& Path::GetEntries() const
{
return m_entries;
}
void Path::Push(PathEntry entry)
{
m_entries.push_back(AZStd::move(entry));
}
void Path::Push(size_t entry)
{
Push(PathEntry(entry));
}
void Path::Push(AZ::Name entry)
{
Push(PathEntry(AZStd::move(entry)));
}
void Path::Push(AZStd::string_view entry)
{
Push(AZ::Name(entry));
}
void Path::Pop()
{
m_entries.pop_back();
}
void Path::Clear()
{
m_entries.clear();
}
PathEntry Path::At(size_t index) const
{
if (index < m_entries.size())
{
return m_entries[index];
}
return {};
}
size_t Path::Size() const
{
return m_entries.size();
}
PathEntry& Path::operator[](size_t index)
{
return m_entries[index];
}
const PathEntry& Path::operator[](size_t index) const
{
return m_entries[index];
}
Path::ContainerType::iterator Path::begin()
{
return m_entries.begin();
}
Path::ContainerType::iterator Path::end()
{
return m_entries.end();
}
Path::ContainerType::const_iterator Path::begin() const
{
return m_entries.cbegin();
}
Path::ContainerType::const_iterator Path::end() const
{
return m_entries.cend();
}
Path::ContainerType::const_iterator Path::cbegin() const
{
return m_entries.cbegin();
}
Path::ContainerType::const_iterator Path::cend() const
{
return m_entries.cend();
}
size_t Path::size() const
{
return m_entries.size();
}
size_t Path::GetStringLength() const
{
size_t size = 0;
for (const PathEntry& entry : m_entries)
{
++size;
if (entry.IsEndOfArray())
{
size += 1;
}
else if (entry.IsIndex())
{
const size_t index = entry.GetIndex();
const double digitCount = index > 0 ? log10(aznumeric_cast<double>(index + 1)) : 1.0;
size += aznumeric_cast<size_t>(ceil(digitCount));
}
else
{
const char* nameBuffer = entry.GetKey().GetCStr();
for (size_t i = 0; nameBuffer[i]; ++i)
{
if (nameBuffer[i] == EscapeCharacter || nameBuffer[i] == PathSeparator)
{
++size;
}
++size;
}
}
}
return size;
}
void Path::FormatString(char* stringBuffer, size_t bufferSize) const
{
size_t bufferIndex = 0;
auto putChar = [&](char c)
{
if (bufferIndex == bufferSize)
{
return;
}
stringBuffer[bufferIndex++] = c;
};
auto writeToBuffer = [&](const char* key)
{
for (size_t keyIndex = 0; key[keyIndex]; ++keyIndex)
{
const char c = key[keyIndex];
if (c == EscapeCharacter)
{
putChar(EscapeCharacter);
putChar(TildeSequence);
}
else if (c == PathSeparator)
{
putChar(EscapeCharacter);
putChar(ForwardSlashSequence);
}
else
{
putChar(c);
}
}
};
for (const PathEntry& entry : m_entries)
{
putChar(PathSeparator);
if (entry.IsEndOfArray())
{
putChar(EndOfArrayCharacter);
}
else if (entry.IsIndex())
{
bufferIndex += azsnprintf(&stringBuffer[bufferIndex], bufferSize - bufferIndex, "%zu", entry.GetIndex());
}
else
{
writeToBuffer(entry.GetKey().GetCStr());
}
}
putChar('\0');
}
AZStd::string Path::ToString() const
{
AZStd::string formattedString;
const size_t size = GetStringLength();
formattedString.resize_no_construct(size);
FormatString(formattedString.data(), size + 1);
return formattedString;
}
void Path::AppendToString(AZStd::string& output) const
{
const size_t startIndex = output.length();
const size_t stringLength = GetStringLength();
output.resize_no_construct(startIndex + stringLength);
FormatString(output.data() + startIndex, stringLength + 1);
}
void Path::FromString(AZStd::string_view pathString)
{
m_entries.clear();
if (pathString.empty())
{
return;
}
size_t pathEntryCount = 0;
for (size_t i = 1; i <= pathString.size(); ++i)
{
if (pathString[i] == PathSeparator)
{
++pathEntryCount;
}
}
m_entries.reserve(pathEntryCount);
// Ignore a preceeding path separator and start processing after it
size_t pathIndex = pathString[0] == PathSeparator ? 1 : 0;
bool isNumber = true;
AZStd::string convertedSection;
for (size_t i = pathIndex; i <= pathString.size(); ++i)
{
if (i == pathString.size() || pathString[i] == PathSeparator)
{
AZStd::string_view section = pathString.substr(pathIndex, i - pathIndex);
if (section.size() == 1 && section[0] == EndOfArrayCharacter)
{
PathEntry entry;
entry.SetEndOfArray();
m_entries.push_back(AZStd::move(entry));
}
else if (isNumber && !section.empty())
{
size_t index = 0;
ConsoleTypeHelpers::StringToValue(index, section);
m_entries.push_back(PathEntry{ index });
}
else
{
convertedSection.clear();
size_t lastPos = 0;
size_t posToEscape = section.find(EscapeCharacter);
while (posToEscape != AZStd::string_view::npos)
{
if (convertedSection.empty())
{
convertedSection.reserve(section.size() - 1);
}
convertedSection += section.substr(lastPos, posToEscape - lastPos);
if (section[posToEscape + 1] == ForwardSlashSequence)
{
convertedSection += '/';
}
else
{
convertedSection += '~';
}
lastPos = posToEscape + 2;
posToEscape = section.find(EscapeCharacter, posToEscape + 2);
}
if (!convertedSection.empty())
{
convertedSection += section.substr(lastPos);
m_entries.emplace_back(convertedSection);
}
else
{
m_entries.emplace_back(section);
}
}
pathIndex = i + 1;
isNumber = true;
continue;
}
const char c = pathString[i];
isNumber = isNumber && c >= '0' && c <= '9';
}
}
} // namespace AZ::Dom
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Name/Name.h>
#include <AzCore/std/containers/variant.h>
#include <AzCore/std/containers/vector.h>
namespace AZ::Dom
{
//! Represents the path to a direct descendant of a Value.
//! PathEntry may be one of the following:
//! - Index, a numerical index for indexing within Arrays and Nodes
//! - Key, a name for indexing within Objects and Nodes
//! - EndOfArray, a special-case indicator for representing the end of an array
//! used by the patching system to represent push / pop back operations.
class PathEntry final
{
public:
static constexpr size_t EndOfArrayIndex = size_t(-1);
PathEntry() = default;
PathEntry(const PathEntry&) = default;
PathEntry(PathEntry&&) = default;
explicit PathEntry(size_t value);
explicit PathEntry(AZ::Name value);
explicit PathEntry(AZStd::string_view value);
PathEntry& operator=(const PathEntry&) = default;
PathEntry& operator=(PathEntry&&) = default;
PathEntry& operator=(size_t value);
PathEntry& operator=(AZ::Name value);
PathEntry& operator=(AZStd::string_view value);
bool operator==(const PathEntry& other) const;
bool operator==(size_t index) const;
bool operator==(const AZ::Name& key) const;
bool operator==(AZStd::string_view key) const;
bool operator!=(const PathEntry& other) const;
bool operator!=(size_t index) const;
bool operator!=(const AZ::Name& key) const;
bool operator!=(AZStd::string_view key) const;
void SetEndOfArray();
bool IsEndOfArray() const;
bool IsIndex() const;
bool IsKey() const;
size_t GetIndex() const;
const AZ::Name& GetKey() const;
private:
AZStd::variant<size_t, AZ::Name> m_value;
};
//! Represents a path, represented as a series of PathEntry values, to a position in a Value.
class Path final
{
public:
using ContainerType = AZStd::vector<PathEntry>;
static constexpr char PathSeparator = '/';
static constexpr char EscapeCharacter = '~';
static constexpr char TildeSequence = '0';
static constexpr char ForwardSlashSequence = '1';
static constexpr char EndOfArrayCharacter = '-';
Path() = default;
Path(const Path&) = default;
Path(Path&&) = default;
explicit Path(AZStd::initializer_list<PathEntry> init);
//! Creates a Path from a path string, a path string is formatted per the JSON pointer specification
//! and looks like "/path/to/value/0"
explicit Path(AZStd::string_view pathString);
template<class InputIterator>
explicit Path(InputIterator first, InputIterator last)
: m_entries(first, last)
{
}
Path& operator=(const Path&) = default;
Path& operator=(Path&&) = default;
Path operator/(const PathEntry&) const;
Path operator/(size_t) const;
Path operator/(AZ::Name) const;
Path operator/(AZStd::string_view) const;
Path operator/(const Path&) const;
Path& operator/=(const PathEntry&);
Path& operator/=(size_t);
Path& operator/=(AZ::Name);
Path& operator/=(AZStd::string_view);
Path& operator/=(const Path&);
bool operator==(const Path&) const;
const ContainerType& GetEntries() const;
void Push(PathEntry entry);
void Push(size_t entry);
void Push(AZ::Name entry);
void Push(AZStd::string_view key);
void Pop();
void Clear();
PathEntry At(size_t index) const;
size_t Size() const;
PathEntry& operator[](size_t index);
const PathEntry& operator[](size_t index) const;
ContainerType::iterator begin();
ContainerType::iterator end();
ContainerType::const_iterator begin() const;
ContainerType::const_iterator end() const;
ContainerType::const_iterator cbegin() const;
ContainerType::const_iterator cend() const;
size_t size() const;
//! Gets the length this path would require, if string-formatted.
//! The length includes the contents of the string but not a null terminator.
size_t GetStringLength() const;
//! Formats a JSON-pointer style path string into the target buffer.
//! This operation will fail if bufferSize < GetStringLength() + 1
void FormatString(char* stringBuffer, size_t bufferSize) const;
//! Returns a JSON-pointer style path string for this path.
AZStd::string ToString() const;
void AppendToString(AZStd::string& output) const;
//! Reads a JSON-pointer style path from pathString and replaces this path's contents.
//! Paths are accepted in the following forms:
//! "/path/to/foo/0"
//! "path/to/foo/0"
void FromString(AZStd::string_view pathString);
private:
ContainerType m_entries;
};
} // namespace AZ::Dom
@@ -77,8 +77,8 @@ namespace AZ::Dom::Utils
for (size_t i = 0; i < ourValues.size(); ++i)
{
const Object::EntryType& lhsChild = ourValues[i];
const Object::EntryType& rhsChild = theirValues[i];
if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second))
auto rhsIt = rhs.FindMember(lhsChild.first);
if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second))
{
return false;
}
@@ -144,8 +144,8 @@ namespace AZ::Dom::Utils
for (size_t i = 0; i < ourProperties.size(); ++i)
{
const Object::EntryType& lhsChild = ourProperties[i];
const Object::EntryType& rhsChild = theirProperties[i];
if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second))
auto rhsIt = rhs.FindMember(lhsChild.first);
if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second))
{
return false;
}
+160 -66
View File
@@ -6,6 +6,7 @@
*
*/
#include <AzCore/DOM/DomPath.h>
#include <AzCore/DOM/DomValue.h>
#include <AzCore/DOM/DomValueWriter.h>
#include <AzCore/std/smart_ptr/make_shared.h>
@@ -283,64 +284,33 @@ namespace AZ::Dom
Type Dom::Value::GetType() const
{
return AZStd::visit(
[](auto&& value) -> Type
{
using CurrentType = AZStd::decay_t<decltype(value)>;
if constexpr (AZStd::is_same_v<CurrentType, AZStd::monostate>)
{
return Type::Null;
}
else if constexpr (AZStd::is_same_v<CurrentType, int64_t>)
{
return Type::Int64;
}
else if constexpr (AZStd::is_same_v<CurrentType, uint64_t>)
{
return Type::Uint64;
}
else if constexpr (AZStd::is_same_v<CurrentType, double>)
{
return Type::Double;
}
else if constexpr (AZStd::is_same_v<CurrentType, bool>)
{
return Type::Bool;
}
else if constexpr (AZStd::is_same_v<CurrentType, AZStd::string_view>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, SharedStringType>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, ShortStringType>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, ObjectPtr>)
{
return Type::Object;
}
else if constexpr (AZStd::is_same_v<CurrentType, ArrayPtr>)
{
return Type::Array;
}
else if constexpr (AZStd::is_same_v<CurrentType, NodePtr>)
{
return Type::Node;
}
else if constexpr (AZStd::is_same_v<CurrentType, OpaqueStorageType>)
{
return Type::Opaque;
}
else
{
AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type");
}
},
m_value);
switch (m_value.index())
{
case GetTypeIndex<AZStd::monostate>():
return Type::Null;
case GetTypeIndex<int64_t>():
return Type::Int64;
case GetTypeIndex<uint64_t>():
return Type::Uint64;
case GetTypeIndex<double>():
return Type::Double;
case GetTypeIndex<bool>():
return Type::Bool;
case GetTypeIndex<AZStd::string_view>():
case GetTypeIndex<SharedStringType>():
case GetTypeIndex<ShortStringType>():
return Type::String;
case GetTypeIndex<ObjectPtr>():
return Type::Object;
case GetTypeIndex<ArrayPtr>():
return Type::Array;
case GetTypeIndex<NodePtr>():
return Type::Node;
case GetTypeIndex<AZStd::shared_ptr<AZStd::any>>():
return Type::Opaque;
}
AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type");
return Type::Null;
}
bool Value::IsNull() const
@@ -594,12 +564,12 @@ namespace AZ::Dom
return GetObjectInternal().end();
}
Object::Iterator Value::MemberBegin()
Object::Iterator Value::MutableMemberBegin()
{
return GetObjectInternal().begin();
}
Object::Iterator Value::MemberEnd()
Object::Iterator Value::MutableMemberEnd()
{
return GetObjectInternal().end();
}
@@ -725,12 +695,12 @@ namespace AZ::Dom
return object.end();
}
Object::Iterator Value::EraseMember(Object::ConstIterator pos)
Object::Iterator Value::EraseMember(Object::Iterator pos)
{
return GetObjectInternal().erase(pos);
}
Object::Iterator Value::EraseMember(Object::ConstIterator first, Object::ConstIterator last)
Object::Iterator Value::EraseMember(Object::Iterator first, Object::Iterator last)
{
return GetObjectInternal().erase(first, last);
}
@@ -811,12 +781,12 @@ namespace AZ::Dom
return GetArrayInternal().end();
}
Array::Iterator Value::ArrayBegin()
Array::Iterator Value::MutableArrayBegin()
{
return GetArrayInternal().begin();
}
Array::Iterator Value::ArrayEnd()
Array::Iterator Value::MutableArrayEnd()
{
return GetArrayInternal().end();
}
@@ -843,12 +813,12 @@ namespace AZ::Dom
return *this;
}
Array::Iterator Value::ArrayErase(Array::ConstIterator pos)
Array::Iterator Value::ArrayErase(Array::Iterator pos)
{
return GetArrayInternal().erase(pos);
}
Array::Iterator Value::ArrayErase(Array::ConstIterator first, Array::ConstIterator last)
Array::Iterator Value::ArrayErase(Array::Iterator first, Array::Iterator last)
{
return GetArrayInternal().erase(first, last);
}
@@ -1113,6 +1083,10 @@ namespace AZ::Dom
{
result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent);
}
else if constexpr (AZStd::is_same_v<Alternative, ShortStringType>)
{
result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent);
}
else if constexpr (AZStd::is_same_v<Alternative, ObjectPtr>)
{
result = visitor.StartObject();
@@ -1204,4 +1178,124 @@ namespace AZ::Dom
{
return m_value;
}
Value& Value::operator[](const PathEntry& entry)
{
if (entry.IsEndOfArray())
{
Array::ContainerType& array = GetArrayInternal();
array.push_back();
return array[array.size() - 1];
}
return entry.IsIndex() ? operator[](entry.GetIndex()) : operator[](entry.GetKey());
}
const Value& Value::operator[](const PathEntry& entry) const
{
return entry.IsIndex() ? operator[](entry.GetIndex()) : operator[](entry.GetKey());
}
Value& Value::operator[](const Path& path)
{
Value* value = this;
for (const PathEntry& entry : path)
{
value = &value->operator[](entry);
}
return *value;
}
const Value& Value::operator[](const Path& path) const
{
const Value* value = this;
for (const PathEntry& entry : path)
{
value = &value->operator[](entry);
}
return *value;
}
const Value* Value::FindChild(const PathEntry& entry) const
{
if (entry.IsEndOfArray())
{
return nullptr;
}
else if (entry.IsIndex())
{
const Array::ContainerType& array = GetArrayInternal();
const size_t index = entry.GetIndex();
if (index < array.size())
{
return &array[index];
}
}
else
{
const Object::ContainerType& obj = GetObjectInternal();
auto memberIt = FindMember(entry.GetKey());
if (memberIt != obj.end())
{
return &memberIt->second;
}
}
return nullptr;
}
Value* Value::FindMutableChild(const PathEntry& entry)
{
if (entry.IsEndOfArray())
{
Array::ContainerType& array = GetArrayInternal();
array.push_back();
return &array[array.size() - 1];
}
else if (entry.IsIndex())
{
Array::ContainerType& array = GetArrayInternal();
const size_t index = entry.GetIndex();
if (index < array.size())
{
return &array[index];
}
}
else
{
Object::ContainerType& obj = GetObjectInternal();
auto memberIt = FindMutableMember(entry.GetKey());
if (memberIt != obj.end())
{
return &memberIt->second;
}
}
return nullptr;
}
const Value* Value::FindChild(const Path& path) const
{
const Value* value = this;
for (const PathEntry& entry : path)
{
value = value->FindChild(entry);
if (value == nullptr)
{
return nullptr;
}
}
return value;
}
Value* Value::FindMutableChild(const Path& path)
{
Value* value = this;
for (const PathEntry& entry : path)
{
value = value->FindMutableChild(entry);
if (value == nullptr)
{
return nullptr;
}
}
return value;
}
} // namespace AZ::Dom
+21 -8
View File
@@ -22,6 +22,8 @@
namespace AZ::Dom
{
class PathEntry;
class Path;
using KeyType = AZ::Name;
//! The type of underlying value stored in a value. \see Value
@@ -268,8 +270,8 @@ namespace AZ::Dom
Object::ConstIterator MemberBegin() const;
Object::ConstIterator MemberEnd() const;
Object::Iterator MemberBegin();
Object::Iterator MemberEnd();
Object::Iterator MutableMemberBegin();
Object::Iterator MutableMemberEnd();
Object::Iterator FindMutableMember(KeyType name);
Object::Iterator FindMutableMember(AZStd::string_view name);
@@ -289,8 +291,8 @@ namespace AZ::Dom
void RemoveMember(KeyType name);
void RemoveMember(AZStd::string_view name);
Object::Iterator RemoveMember(Object::Iterator pos);
Object::Iterator EraseMember(Object::ConstIterator pos);
Object::Iterator EraseMember(Object::ConstIterator first, Object::ConstIterator last);
Object::Iterator EraseMember(Object::Iterator pos);
Object::Iterator EraseMember(Object::Iterator first, Object::Iterator last);
Object::Iterator EraseMember(KeyType name);
Object::Iterator EraseMember(AZStd::string_view name);
@@ -313,15 +315,15 @@ namespace AZ::Dom
Array::ConstIterator ArrayBegin() const;
Array::ConstIterator ArrayEnd() const;
Array::Iterator ArrayBegin();
Array::Iterator ArrayEnd();
Array::Iterator MutableArrayBegin();
Array::Iterator MutableArrayEnd();
Value& ArrayReserve(size_t newCapacity);
Value& ArrayPushBack(Value value);
Value& ArrayPopBack();
Array::Iterator ArrayErase(Array::ConstIterator pos);
Array::Iterator ArrayErase(Array::ConstIterator first, Array::ConstIterator last);
Array::Iterator ArrayErase(Array::Iterator pos);
Array::Iterator ArrayErase(Array::Iterator first, Array::Iterator last);
Array::ContainerType& GetMutableArray();
const Array::ContainerType& GetArray() const;
@@ -380,6 +382,17 @@ namespace AZ::Dom
Visitor::Result Accept(Visitor& visitor, bool copyStrings) const;
AZStd::unique_ptr<Visitor> GetWriteHandler();
// Path API...
Value& operator[](const PathEntry& entry);
const Value& operator[](const PathEntry& entry) const;
Value& operator[](const Path& path);
const Value& operator[](const Path& path) const;
const Value* FindChild(const PathEntry& entry) const;
Value* FindMutableChild(const PathEntry& entry);
const Value* FindChild(const Path& path) const;
Value* FindMutableChild(const Path& path);
//! Gets the internal value of this Value. Note that this value's types may not correspond one-to-one with the Type enumeration,
//! as internally the same type might have different storage mechanisms. Where possible, prefer using the typed API.
const ValueType& GetInternalValue() const;
+7 -2
View File
@@ -23,6 +23,11 @@
#include <AzCore/EBus/Results.h>
#include <AzCore/EBus/Internal/Debug.h>
// Included for backwards compatibility purposes
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/typetraits/is_same.h>
#include <AzCore/std/utils.h>
@@ -515,7 +520,7 @@ namespace AZ
* This is not EBus Context Mutex when LocklessDispatch is set
*/
template <typename DispatchMutex>
using DispatchLockGuard = typename ImplTraits::template DispatchLockGuard<DispatchMutex>;
using DispatchLockGuardTemplate = typename ImplTraits::template DispatchLockGuard<DispatchMutex>;
//////////////////////////////////////////////////////////////////////////
// Check to help identify common mistakes
@@ -645,7 +650,7 @@ namespace AZ
* during broadcast/event dispatch.
* @see EBusTraits::LocklessDispatch
*/
using DispatchLockGuard = DispatchLockGuard<ContextMutexType>;
using DispatchLockGuard = DispatchLockGuardTemplate<ContextMutexType>;
/**
* The scoped lock guard to use during connection. Some specialized policies execute handler methods which
@@ -93,14 +93,14 @@ namespace AZ
// This struct will hold the handlers per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder)
using AddressStorage = AddressStoragePolicy<Traits, HandlerHolder>;
// Defines how handlers are stored per address (will be some sort of list)
using HandlerStorage = HandlerStoragePolicy<Interface, Traits, HandlerNode>;
using Handler = IdHandler<Interface, Traits, ContainerType>;
using MultiHandler = MultiHandler<Interface, Traits, ContainerType>;
using MultiHandler = AZ::Internal::MultiHandler<Interface, Traits, ContainerType>;
using BusPtr = AZStd::intrusive_ptr<HandlerHolder>;
EBusContainer() = default;
@@ -774,13 +774,13 @@ namespace AZ
// This struct will hold the handler per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder)
using AddressStorage = AddressStoragePolicy<Traits, HandlerHolder>;
// No need for HandlerStorage, there's only 1 so it will always just be a HandlerNode*
using Handler = IdHandler<Interface, Traits, ContainerType>;
using MultiHandler = MultiHandler<Interface, Traits, ContainerType>;
using MultiHandler = AZ::Internal::MultiHandler<Interface, Traits, ContainerType>;
using BusPtr = AZStd::intrusive_ptr<HandlerHolder>;
EBusContainer() = default;
@@ -1316,7 +1316,7 @@ namespace AZ
// This struct will hold the handlers per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handlers are stored per address (will be some sort of list)
using HandlerStorage = HandlerStoragePolicy<Interface, Traits, HandlerNode>;
// No need for AddressStorage, there's only 1
@@ -161,7 +161,7 @@ namespace AZ
template <class C>
struct EBusCallstackStorage<C, true>
{
AZ_THREAD_LOCAL static C* s_entry;
static AZ_THREAD_LOCAL C* s_entry;
EBusCallstackStorage() = default;
~EBusCallstackStorage() = default;
+43 -51
View File
@@ -13,50 +13,6 @@
#include <AzCore/IO/Path/PathIterable.inl>
// extern instantiations of Path templates to prevent implicit instantiations
namespace AZ::IO
{
// Class templates explicit declarations
extern template class BasicPath<AZStd::string>;
extern template class BasicPath<FixedMaxPathString>;
extern template class PathIterator<PathView>;
extern template class PathIterator<Path>;
extern template class PathIterator<FixedMaxPath>;
// Swap function explicit declarations
extern template void swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
extern template void swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
// Hash function explicit declarations
extern template size_t hash_value<AZStd::string>(const Path& pathToHash);
extern template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
// Append operator explicit declarations
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
const typename BasicPath<AZStd::string>::value_type* rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
const typename BasicPath<FixedMaxPathString>::value_type* rhs);
// Iterator compare explicit declarations
extern template bool operator==<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator==<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator==<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
extern template bool operator!=<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator!=<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
}
//! PathView implementation
namespace AZ::IO
{
@@ -939,13 +895,13 @@ namespace AZ::IO
// then it has no root directory nor filename
if (rootNameView.end() == m_path.end())
{
// has_root_directory || has_filename = false
// If the root name is of the form
// # C: - then it isn't absolute unless it has a root directory C:\
// # \\?\ = is a UNC path that can't exist without a root directory
// # \\server - Is absolute, but has no root directory
// Therefore if the rootName is larger than three characters
// then append the path separator
/* has_root_directory || has_filename = false
If the root name is of the form
C: - then it isn't absolute unless it has a root directory C:\.
\\?\ = is a UNC path that can't exist without a root directory.
\\server - Is absolute, but has no root directory.
Therefore if the rootName is larger than three characters
then append the path separator. */
if (rootNameView.size() >= 3)
{
m_path.push_back(m_preferred_separator);
@@ -1550,3 +1506,39 @@ namespace AZ::IO
return AZStd::hash<PathView>{}(pathToHash);
}
}
// extern instantiations of Path templates to prevent implicit instantiations
namespace AZ::IO
{
// Swap function explicit declarations
extern template void swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
extern template void swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
// Hash function explicit declarations
extern template size_t hash_value<AZStd::string>(const Path& pathToHash);
extern template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
// Append operator explicit declarations
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
const typename BasicPath<AZStd::string>::value_type* rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
const typename BasicPath<FixedMaxPathString>::value_type* rhs);
// Iterator compare explicit declarations
extern template bool operator==<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator==<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator==<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
extern template bool operator!=<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator!=<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
}
@@ -14,7 +14,7 @@
#define az_clz_u64(x) _lzcnt_u64(x)
#define az_popcnt_u32(x) __popcnt(x)
#define az_popcnt_u64(x) __popcnt64(x)
#elif defined(AZ_COMPILER_CLANG)
#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#define az_ctz_u32(x) __builtin_ctz(x)
#define az_ctz_u64(x) __builtin_ctzll(x)
#define az_clz_u32(x) __builtin_clz(x)
@@ -22,5 +22,5 @@
#define az_popcnt_u32(x) __builtin_popcount(x)
#define az_popcnt_u64(x) __builtin_popcountll(x)
#else
#error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isn't supported for this compiler
#error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isnt supported for this compiler
#endif
@@ -39,6 +39,9 @@ namespace AZ
template<typename T> constexpr friend void AZStd::destroy_at(T*);
public:
AllocatorManager();
typedef AZStd::function<void (IAllocator* allocator, size_t /*byteSize*/, size_t /*alignment*/, int/* flags*/, const char* /*name*/, const char* /*fileName*/, int lineNum /*=0*/)> OutOfMemoryCBType;
static void PreRegisterAllocator(IAllocator* allocator); // Only call if the environment is not yet attached
@@ -185,7 +188,6 @@ namespace AZ
AZ::Debug::AllocationRecords::Mode m_defaultTrackingRecordMode;
AZStd::unique_ptr<AZ::MallocSchema, void(*)(AZ::MallocSchema*)> m_mallocSchema;
AllocatorManager();
~AllocatorManager();
static AllocatorManager g_allocMgr; ///< The single instance of the allocator manager
@@ -45,7 +45,9 @@ namespace AZ
//! that already exist.
class NameDictionary final
{
public:
AZ_CLASS_ALLOCATOR(NameDictionary, AZ::OSAllocator, 0);
private:
friend Module;
friend Name;
@@ -75,8 +77,8 @@ namespace AZ
//! @return A Name instance. If the hash was not found, the Name will be empty.
Name FindName(Name::Hash hash) const;
private:
NameDictionary();
private:
~NameDictionary();
void ReportStats() const;
+85 -7
View File
@@ -10,10 +10,17 @@
//////////////////////////////////////////////////////////////////////////
// Platforms
#include <AzCore/variadic.h>
#include "PlatformRestrictedFileDef.h"
#if defined(__clang__)
#define AZ_COMPILER_CLANG __clang_major__
#elif defined(__GNUC__)
// Assign AZ_COMPILER_GCC to a number that represents the major+minor (2 digits) + path level (2 digits) i.e. 3.2.0 == 30200
#define AZ_COMPILER_GCC (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#elif defined(_MSC_VER)
#define AZ_COMPILER_MSVC _MSC_VER
#else
@@ -29,7 +36,7 @@
#define AZ_DYNAMIC_LIBRARY_PREFIX AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX
#define AZ_DYNAMIC_LIBRARY_EXTENSION AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION
#if defined(AZ_COMPILER_CLANG)
#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#define AZ_DLL_EXPORT AZ_TRAIT_OS_DLL_EXPORT_CLANG
#define AZ_DLL_IMPORT AZ_TRAIT_OS_DLL_IMPORT_CLANG
#elif defined(AZ_COMPILER_MSVC)
@@ -67,12 +74,36 @@
#if defined(AZ_COMPILER_MSVC)
/// Disables a warning using push style. For use matched with an AZ_POP_WARNING
#define AZ_PUSH_DISABLE_WARNING(_msvcOption, __) \
__pragma(warning(push)) \
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG
#define AZ_POP_DISABLE_WARNING_MSVC \
__pragma(warning(pop))
#define AZ_POP_DISABLE_WARNING_GCC
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_msvcOption) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_2(_msvcOption, _2) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_3(_msvcOption, _2, _3) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING \
#define AZ_POP_DISABLE_WARNING \
__pragma(warning(pop))
@@ -94,17 +125,62 @@
# define AZ_FUNCTION_SIGNATURE __FUNCSIG__
//////////////////////////////////////////////////////////////////////////
#elif defined(AZ_COMPILER_CLANG)
#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#if defined(AZ_COMPILER_CLANG)
/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING
#define AZ_PUSH_DISABLE_WARNING(__, _clangOption) \
_Pragma("clang diagnostic push") \
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) \
_Pragma("clang diagnostic push") \
_Pragma(AZ_STRINGIZE(clang diagnostic ignored _clangOption))
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption)
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG \
_Pragma("clang diagnostic pop")
#define AZ_POP_DISABLE_WARNING_MSVC
#define AZ_POP_DISABLE_WARNING_GCC
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_1)
#define AZ_PUSH_DISABLE_WARNING_2(_1, _clangOption) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_3(_1, _clangOption, _2) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING \
_Pragma("clang diagnostic pop")
#else
/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) \
_Pragma("GCC diagnostic push") \
_Pragma(AZ_STRINGIZE(GCC diagnostic ignored _gccOption))
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG
#define AZ_POP_DISABLE_WARNING_MSVC
#define AZ_POP_DISABLE_WARNING_GCC \
_Pragma("GCC diagnostic pop")
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_1)
#define AZ_PUSH_DISABLE_WARNING_2(_1, _2)
#define AZ_PUSH_DISABLE_WARNING_3(_1, _2, _gccOption) AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING
_Pragma("GCC diagnostic pop")
#endif // defined(AZ_COMPILER_CLANG)
#define AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
#define AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
#define AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
@@ -121,6 +197,8 @@
#error Compiler not supported
#endif
#define AZ_PUSH_DISABLE_WARNING(...) AZ_MACRO_SPECIALIZE(AZ_PUSH_DISABLE_WARNING_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// We need to define AZ_DEBUG_BUILD in debug mode. We can also define it in debug optimized mode (left up to the user).
// note that _DEBUG is not in fact always defined on all platforms, and only AZ_DEBUG_BUILD should be relied on.
#if !defined(AZ_DEBUG_BUILD) && defined(_DEBUG)
@@ -1541,7 +1541,7 @@ namespace AZ
}
template<class T>
static bool SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*)
static void SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*)
{
behaviorClass->m_equalityComparer = &DefaultEqualityComparer<T>;
}
@@ -2341,8 +2341,6 @@ namespace AZ
// For some reason the Script.cpp test validates that an incomplete type can be used with the SetResult struct
template<typename T, typename U, typename = void>
static constexpr bool IsCopyAssignable = false;
template<typename T, typename U>
static constexpr bool IsCopyAssignable<T, U, AZStd::void_t<decltype(AZStd::declval<T>() = AZStd::declval<U>())>> = true;
template<class T>
static bool Set(BehaviorValueParameter& param, T&& result, bool IsValueCopy)
@@ -2402,6 +2400,9 @@ namespace AZ
}
};
template<typename T, typename U>
constexpr bool SetResult::IsCopyAssignable<T, U, AZStd::void_t<decltype(AZStd::declval<T>() = AZStd::declval<U>())>> = true;
AZ_FORCE_INLINE BehaviorValueParameter& BehaviorValueParameter::operator=(BehaviorValueParameter&& other)
{
*static_cast<BehaviorParameter*>(this) = AZStd::move(static_cast<BehaviorParameter&&>(other));
+21 -8
View File
@@ -977,26 +977,32 @@ namespace AZ
{
return AzGenericTypeInfo::Uuid<U>();
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class U, typename = void>
#else
template<template<auto...> class U, typename = void>
#endif // defined(AZ_COMPILER_MSVC)
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, AZStd::size_t> class U, typename = void>
template<template<typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, typename, AZStd::size_t> class U, typename = void>
template<template<typename, typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, typename, typename, AZStd::size_t> class U, typename = void>
template<template<typename, typename, typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
@@ -1027,15 +1033,22 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match).
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T, class U>
inline bool RttiIsTypeOf(const U&)
#else
template<template<auto...> class T, class U>
#endif // defined(AZ_COMPILER_MSVC)
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
return AzGenericTypeInfo::Uuid<T>() == RttiTypeId<CheckType, AZ::GenericTypeIdTag>();
}
// Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match).
template<template<typename, AZStd::size_t> class T, class U>
template<template<typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
@@ -1043,7 +1056,7 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match).
template<template<typename, typename, AZStd::size_t> class T, class U>
template<template<typename, typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
@@ -1051,7 +1064,7 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match).
template<template<typename, typename, typename, AZStd::size_t> class T, class U>
template<template<typename, typename, typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
+24 -12
View File
@@ -148,11 +148,18 @@ namespace AZ
{
/// Needs to match declared parameter type.
template <template <typename...> class> constexpr bool false_v1 = false;
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class> constexpr bool false_v2 = false;
#else
template<template<auto...> class> constexpr bool false_v2 = false;
#endif // defined(AZ_COMPILER_MSVC)
template<template<typename, auto> class>
constexpr bool false_v3 = false;
template <template <typename, typename, auto> class> constexpr bool false_v4 = false;
template <template <typename, typename, typename, auto> class> constexpr bool false_v5 = false;
template <template <typename, auto, typename> class> constexpr bool false_v6 = false;
template<typename T>
inline const AZ::TypeId& Uuid()
@@ -167,8 +174,13 @@ namespace AZ
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T>
#else
template<template<auto...> class T>
#endif // defined(AZ_COMPILER_MSVC)
inline const AZ::TypeId& Uuid()
{
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -176,7 +188,8 @@ namespace AZ
return s_uuid;
}
template<template<typename, AZStd::size_t> class T>
template<template<typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -184,7 +197,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, typename, AZStd::size_t> class T>
template<template<typename, typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -192,7 +205,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, typename, typename, AZStd::size_t> class T>
template<template<typename, typename, typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -200,7 +213,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, AZStd::size_t, typename> class T>
template<template<typename, auto, typename> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -689,8 +702,7 @@ namespace AZ
#define AZ_TYPE_INFO_INTERNAL_CLASS_VARARGS__UUID(Tag, A) AZ::Internal::AggregateTypes< A... >::template Uuid< Tag >()
#define AZ_TYPE_INFO_INTERNAL_CLASS_VARARGS__NAME(A) AZ::Internal::AggregateTypes< A... >::TypeName(typeName, AZ_ARRAY_SIZE(typeName));
// Once C++17 has been introduced size_t can be replaced with auto for all integer non-type arguments
#define AZ_TYPE_INFO_INTERNAL_AUTO__TYPE AZStd::size_t
#define AZ_TYPE_INFO_INTERNAL_AUTO__TYPE auto
#define AZ_TYPE_INFO_INTERNAL_AUTO__ARG(A) A
#define AZ_TYPE_INFO_INTERNAL_AUTO__UUID(Tag, A) AZ::Internal::GetTypeId< A , Tag >()
#define AZ_TYPE_INFO_INTERNAL_AUTO__NAME(A) AZ::Internal::AzTypeInfoSafeCat(typeName, AZ_ARRAY_SIZE(typeName), AZ::Internal::GetTypeName< A >())
@@ -796,7 +796,7 @@ namespace AZ
// Note: Always use l over context->NativeContext(), as require may be called from a thread.
using RequireHook = AZStd::function<int(lua_State* lua, ScriptContext* context, const char* module)>;
using StackVariableAllocator = StackVariableAllocator;
using StackVariableAllocator = AZ::StackVariableAllocator;
/// Stack temporary memory
/**
@@ -69,7 +69,13 @@ namespace AZ
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T>
#else
template<template<auto...> class T>
#endif // defined(AZ_COMPILER_MSVC)
SerializerBuilder* HandlesType(bool overwriteExisting = false)
{
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
@@ -17,16 +17,9 @@
#if defined(HAVE_BENCHMARK)
#if defined(AZ_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif // clang
AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations", "-Wdeprecated-declarations")
#include <benchmark/benchmark.h>
#if defined(AZ_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif // clang
AZ_POP_DISABLE_WARNING
#endif // HAVE_BENCHMARK
@@ -9,6 +9,7 @@
set(FILES
base.h
Docs.h
variadic.h
Platform.cpp
Platform.h
PlatformDef.h
@@ -115,6 +116,8 @@ set(FILES
Debug/TraceReflection.h
DOM/DomBackend.cpp
DOM/DomBackend.h
DOM/DomPath.cpp
DOM/DomPath.h
DOM/DomUtils.cpp
DOM/DomUtils.h
DOM/DomValue.cpp
+1 -60
View File
@@ -7,6 +7,7 @@
*/
#pragma once
#include <AzCore/variadic.h>
#include <AzCore/PlatformDef.h> ///< Platform/compiler specific defines
#include <AzCore/base_Platform.h>
@@ -135,66 +136,6 @@
#define AZ_INVALID_POINTER reinterpret_cast<void*>(0x0badf00dul)
// Variadic MACROS util functions
/**
* AZ_VA_NUM_ARGS
* counts number of parameters (up to 10).
* example. AZ_VA_NUM_ARGS(x,y,z) -> expands to 3
*/
#ifndef AZ_VA_NUM_ARGS
# define AZ_VA_HAS_ARGS(...) ""#__VA_ARGS__[0] != 0
// we add the zero to avoid the case when we require at least 1 param at the end...
# define AZ_VA_NUM_ARGS(...) AZ_VA_NUM_ARGS_IMPL_((__VA_ARGS__, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
# define AZ_VA_NUM_ARGS_IMPL_(tuple) AZ_VA_NUM_ARGS_IMPL tuple
# define AZ_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, N, ...) N
// Expands a macro and calls a different macro based on the number of arguments.
//
// Example: We need to specialize a macro for 1 and 2 arguments
// #define AZ_MY_MACRO(...) AZ_MACRO_SPECIALIZE(AZ_MY_MACRO_,AZ_VA_NUM_ARGS(__VA_ARGS__),(__VA_ARGS__))
//
// #define AZ_MY_MACRO_1(_1) /* code for 1 param */
// #define AZ_MY_MACRO_2(_1,_2) /* code for 2 params */
// ... etc.
//
//
// We have 3 levels of macro expansion...
# define AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS) MACRO_NAME##NPARAMS PARAMS
# define AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS)
# define AZ_MACRO_SPECIALIZE(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS)
#endif // AZ_VA_NUM_ARGS
// Out of all supported compilers, mwerks is the only one
// that requires variadic macros to have at least 1 param.
// This is a pain they we use macros to call functions (with no params).
// we implement functions for up to 10 params
#define AZ_FUNCTION_CALL_1(_1) _1()
#define AZ_FUNCTION_CALL_2(_1, _2) _1(_2)
#define AZ_FUNCTION_CALL_3(_1, _2, _3) _1(_2, _3)
#define AZ_FUNCTION_CALL_4(_1, _2, _3, _4) _1(_2, _3, _4)
#define AZ_FUNCTION_CALL_5(_1, _2, _3, _4, _5) _1(_2, _3, _4, _5)
#define AZ_FUNCTION_CALL_6(_1, _2, _3, _4, _5, _6) _1(_2, _3, _4, _5, _6)
#define AZ_FUNCTION_CALL_7(_1, _2, _3, _4, _5, _6, _7) _1(_2, _3, _4, _5, _6, _7)
#define AZ_FUNCTION_CALL_8(_1, _2, _3, _4, _5, _6, _7, _8) _1(_2, _3, _4, _5, _6, _7, _8)
#define AZ_FUNCTION_CALL_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) _1(_2, _3, _4, _5, _6, _7, _8, _9)
#define AZ_FUNCTION_CALL_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) _1(_2, _3, _4, _5, _6, _7, _8, _9, _10)
// We require at least 1 param FunctionName
#define AZ_FUNCTION_CALL(...) AZ_MACRO_SPECIALIZE(AZ_FUNCTION_CALL_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// Based on boost macro expansion fix...
#define AZ_PREVENT_MACRO_SUBSTITUTION
//////////////////////////////////////////////////////////////////////////
#include <cstddef> // the macros NULL and offsetof as well as the types ptrdiff_t, wchar_t, and size_t.
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/std/utils.h>
#include <AzCore/std/typetraits/is_same.h>
#include <AzCore/std/typetraits/is_constructible.h>
#include <AzCore/std/typetraits/remove_cvref.h>
@@ -253,7 +253,7 @@ namespace AZStd::Internal
}
template <typename U, typename = enable_if_t<is_convertible_v<U, T>>>
fixed_non_trivial_storage(AZStd::initializer_list<U> ilist) noexcept(noexcept(emplace_back(AZStd::declval<U>())))
fixed_non_trivial_storage(AZStd::initializer_list<U> ilist) noexcept(noexcept(this->emplace_back(AZStd::declval<U>())))
{
AZSTD_CONTAINER_ASSERT(ilist.size() <= capacity(), "Initializer list cannot be larger than storage capacity");
for (const U& element : ilist)
@@ -79,7 +79,7 @@ namespace AZStd
typedef typename tree_type::const_reverse_iterator const_reverse_iterator;
using node_type = map_node_handle<map_node_traits<key_type, mapped_type, allocator_type, typename tree_type::node_type, typename tree_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE explicit map(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
: m_tree(comp, alloc) {}
@@ -123,7 +123,8 @@ namespace AZStd
}
}
friend void swap(node_handle& lhs, node_handle& rhs);
template <typename SwapNodeTraits, template <typename, typename> class SwapMapOrSetNodeHandleBase>
friend void swap(node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& lhs, node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& rhs);
private:
node_handle(node_pointer_type node, const allocator_type& allocator)
@@ -152,8 +153,8 @@ namespace AZStd
optional<allocator_type> m_allocator;
};
template <typename NodeTraits, template <typename, typename> class MapOrSetNodeHandleBase>
void swap(node_handle<NodeTraits, MapOrSetNodeHandleBase>& lhs, node_handle<NodeTraits, MapOrSetNodeHandleBase>& rhs)
template <typename SwapNodeTraits, template <typename, typename> class SwapMapOrSetNodeHandleBase>
void swap(node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& lhs, node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& rhs)
{
lhs.swap(rhs);
}
@@ -68,7 +68,7 @@ namespace AZStd
typedef typename tree_type::const_reverse_iterator const_reverse_iterator;
using node_type = set_node_handle<set_node_traits<value_type, allocator_type, typename tree_type::node_type, typename tree_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE explicit set(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
: m_tree(comp, alloc) {}
@@ -33,23 +33,24 @@ namespace AZStd
*
* Since the span does not copy and store any data, it is only valid as long as the data used to create it is valid.
*/
template <class Element>
template <class T>
class span final
{
public:
using value_type = Element;
using element_type = T;
using value_type = AZStd::remove_cv_t<T>;
using pointer = value_type*;
using const_pointer = const value_type*;
using pointer = T*;
using const_pointer = const T*;
using reference = value_type&;
using const_reference = const value_type&;
using reference = T&;
using const_reference = const T&;
using size_type = AZStd::size_t;
using difference_type = AZStd::ptrdiff_t;
using iterator = value_type*;
using const_iterator = const value_type*;
using iterator = T*;
using const_iterator = const T*;
using reverse_iterator = AZStd::reverse_iterator<iterator>;
using const_reverse_iterator = AZStd::reverse_iterator<const_iterator>;
@@ -65,21 +66,11 @@ namespace AZStd
// create a span to just the first element instead of an entire array.
constexpr span(const_pointer s) = delete;
template<AZStd::size_t N>
constexpr span(AZStd::array<value_type, N>& data);
template<typename Container>
constexpr span(Container& data);
constexpr span(AZStd::vector<value_type>& data);
template<AZStd::size_t N>
constexpr span(AZStd::fixed_vector<value_type, N>& data);
template<AZStd::size_t N>
constexpr span(const AZStd::array<value_type, N>& data);
constexpr span(const AZStd::vector<value_type>& data);
template<AZStd::size_t N>
constexpr span(const AZStd::fixed_vector<value_type, N>& data);
template<typename Container>
constexpr span(const Container& data);
constexpr span(const span&) = default;
@@ -132,6 +123,7 @@ namespace AZStd
pointer m_begin;
pointer m_end;
};
} // namespace AZStd
#include <AzCore/std/containers/span.inl>
@@ -29,42 +29,16 @@ namespace AZStd
, m_end(last)
{ }
template <class Element>
template<AZStd::size_t N>
inline constexpr span<Element>::span(AZStd::array<Element, N>& data)
template<class Element>
template<typename Container>
inline constexpr span<Element>::span(Container& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
template <class Element>
inline constexpr span<Element>::span(AZStd::vector<Element>& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
template <class Element>
template<AZStd::size_t N>
inline constexpr span<Element>::span(AZStd::fixed_vector<Element, N>& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
template <class Element>
template<AZStd::size_t N>
inline constexpr span<Element>::span(const AZStd::array<Element, N>& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
template <class Element>
inline constexpr span<Element>::span(const AZStd::vector<Element>& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
template <class Element>
template<AZStd::size_t N>
inline constexpr span<Element>::span(const AZStd::fixed_vector<Element, N>& data)
template<class Element>
template<typename Container>
inline constexpr span<Element>::span(const Container& data)
: m_begin(data.data())
, m_end(m_begin + data.size())
{ }
@@ -102,7 +102,7 @@ namespace AZStd
typedef typename base_type::pair_iter_bool pair_iter_bool;
using node_type = map_node_handle<map_node_traits<key_type, mapped_type, allocator_type, typename base_type::list_node_type, typename base_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE unordered_map()
: base_type(hasher(), key_eq(), allocator_type()) {}
@@ -87,7 +87,7 @@ namespace AZStd
typedef typename base_type::const_local_iterator const_local_iterator;
using node_type = set_node_handle<set_node_traits<value_type, allocator_type, typename base_type::list_node_type, typename base_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE unordered_set()
: base_type(hasher(), key_eq(), allocator_type()) {}
@@ -954,25 +954,6 @@ namespace AZStd
return true;
}
/// Validates an iter iterator. Returns a combination of \ref iterator_status_flag.
AZ_FORCE_INLINE int validate_iterator(const iterator& iter) const
{
#ifdef AZSTD_HAS_CHECKED_ITERATORS
AZ_Assert(iter.m_container == this, "Iterator doesn't belong to this container");
pointer iterPtr = iter.m_iter;
#else
pointer iterPtr = iter;
#endif
if (iterPtr < m_start || iterPtr > m_last)
{
return isf_none;
}
else if (iterPtr == m_last)
{
return isf_valid;
}
return isf_valid | isf_can_dereference;
}
AZ_FORCE_INLINE int validate_iterator(const const_iterator& iter) const
{
#ifdef AZSTD_HAS_CHECKED_ITERATORS
@@ -992,7 +973,6 @@ namespace AZStd
return isf_valid | isf_can_dereference;
}
AZ_FORCE_INLINE int validate_iterator(const reverse_iterator& iter) const { return validate_iterator(iter.base()); }
AZ_FORCE_INLINE int validate_iterator(const const_reverse_iterator& iter) const { return validate_iterator(iter.base()); }
/**
@@ -279,11 +279,11 @@ namespace AZStd
reinterpret_cast<functor_type*>(&in_buffer.data);
if (op == clone_functor_tag)
{
new ((void*)&out_buffer.data)functor_type(*in_functor);
AZStd::construct_at(reinterpret_cast<functor_type*>(&out_buffer), functor_type(*in_functor));
}
else if (op == move_functor_tag)
{
new ((void*)&out_buffer.data)functor_type(AZStd::move(*in_functor));
AZStd::construct_at(reinterpret_cast<functor_type*>(&out_buffer), functor_type(AZStd::move(*in_functor)));
// Casting via union to get around compiler warnings (strict type on GCC, unused variable on MSVC)
union
{
@@ -291,7 +291,7 @@ namespace AZStd
assign_functor(FunctionObj&& f, function_buffer& functor, AZStd::true_type)
{
using RawFunctorObjType = AZStd::decay_t<FunctionObj>;
new ((void*)&functor.data)RawFunctorObjType(AZStd::forward<FunctionObj>(f));
AZStd::construct_at(reinterpret_cast<RawFunctorObjType*>(&functor), RawFunctorObjType(AZStd::forward<FunctionObj>(f)));
}
template<typename FunctionObj, typename Allocator>
void
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/typetraits/invoke_traits.h>
namespace AZStd
@@ -30,9 +30,8 @@ namespace AZStd
// #3
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs,
size_type rhsOffset)
size_type rhsOffset) : basic_fixed_string(rhs, rhsOffset, npos)
{ // construct from rhs [rhsOffset, npos)
assign(rhs, rhsOffset, npos);
}
// #3
@@ -40,7 +39,15 @@ namespace AZStd
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs,
size_type rhsOffset, size_type count)
{ // construct from rhs [rhsOffset, rhsOffset + count)
assign(rhs, rhsOffset, count);
AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset");
size_type num = AZStd::min(count, rhs.size() - rhsOffset);
// make room and assign new stuff
pointer data = m_buffer;
const_pointer rhsData = rhs.m_buffer;
Traits::copy(data, rhsData + rhsOffset, num);
m_size = static_cast<internal_size_type>(num);
Traits::assign(data[num], Element()); // terminate
}
// #4
@@ -68,15 +75,18 @@ namespace AZStd
// #7
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs)
: basic_fixed_string(rhs, size_type(0), npos)
{
assign(rhs, size_type(0), npos);
}
// #8
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(basic_fixed_string&& rhs)
{
assign(AZStd::move(rhs));
Traits::copy(m_buffer, rhs.m_buffer, rhs.size() + 1);
m_size = rhs.m_size;
rhs.m_size = 0;
Traits::assign(rhs.m_buffer[0], Element{});
}
// #9
@@ -18,6 +18,8 @@
#include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/typetraits/alignment_of.h>
#include <AzCore/std/typetraits/is_convertible.h>
#include <AzCore/std/typetraits/is_integral.h>
#include <AzCore/std/string/string_view.h>
@@ -1483,11 +1485,11 @@ namespace AZStd
}
};
// Clang supports compile-time check for printf-like signatures
// Clang/GCC supports compile-time check for printf-like signatures
// On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check
// For not affecting final release binary size, we don't use the templated version on Release configuration either
#if AZ_COMPILER_CLANG || defined(_PREFAST_) || defined(_RELEASE)
# if AZ_COMPILER_CLANG
#if AZ_COMPILER_CLANG || AZ_COMPILER_GCC || defined(_PREFAST_) || defined(_RELEASE)
# if AZ_COMPILER_CLANG || AZ_COMPILER_GCC
# define FORMAT_FUNC __attribute__((format(printf, 1, 2)))
# define FORMAT_FUNC_ARG
# elif AZ_COMPILER_MSVC
@@ -308,34 +308,71 @@ namespace AZStd
}
static constexpr bool eq(char_type left, char_type right) noexcept { return left == right; }
static constexpr bool lt(char_type left, char_type right) noexcept { return left < right; }
static constexpr int compare(const char_type* s1, const char_type* s2, size_t count) noexcept
static constexpr int compare(const char_type* s1, const char_type* s2, size_t count) noexcept
{
// In GCC versions prior to major version 10, __builtin_memcmp fails in valid checks in constexpr evaluation
#if !defined(AZ_COMPILER_GCC) || AZ_COMPILER_GCC >= 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_memcmp(s1, s2, count);
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemcmp(s1, s2, count);
} else
#endif
{
if (az_builtin_is_constant_evaluated())
{
for (; count; --count, ++s1, ++s2)
{
if (lt(*s1, *s2))
{
return -1;
}
else if (lt(*s2, *s1))
{
return 1;
}
}
return 0;
}
else
{
return ::memcmp(s1, s2, count * sizeof(char_type));
}
}
}
static constexpr size_t length(const char_type* s) noexcept
{
// For GCC versions less than 10, __builtin_strlen and __builtin_wcslen is not supported as const expressions
// so for that case it will need to manually count the characters (at compile time) instead
#if defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_memcmp(s1, s2, count);
if (!az_builtin_is_constant_evaluated())
{
return strlen(s);
}
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemcmp(s1, s2, count);
}
else
{
for (; count; --count, ++s1, ++s2)
if (!az_builtin_is_constant_evaluated())
{
if (lt(*s1, *s2))
{
return -1;
}
else if (lt(*s2, *s1))
{
return 1;
}
return wcslen(s);
}
return 0;
}
}
static constexpr size_t length(const char_type* s) noexcept
{
size_t strLength{};
for (; *s; ++s, ++strLength)
{
;
}
return strLength;
#else
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_strlen(s);
@@ -353,9 +390,39 @@ namespace AZStd
}
return strLength;
}
#endif // defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
}
static constexpr const char_type* find(const char_type* s, size_t count, const char_type& ch) noexcept
{
// For GCC versions less than 10, __builtin_char_memchr and __builtin_wmemchr is not supported, and
// __builtin_memchr is not supported as const expressions. In those cases we will manually locate and
// return the pointer to 's' (at compile time)
#if defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
if (!az_builtin_is_constant_evaluated())
{
return static_cast<const char_type*>(__builtin_memchr(s, ch, count));
}
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
if (!az_builtin_is_constant_evaluated())
{
return wmemchr(s, ch, count);
}
}
for (; count; --count, ++s)
{
if (eq(*s, ch))
{
return s;
}
}
return nullptr;
#else
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_char_memchr(s, ch, count);
@@ -363,7 +430,6 @@ namespace AZStd
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemchr(s, ch, count);
}
else
{
@@ -376,6 +442,7 @@ namespace AZStd
}
return nullptr;
}
#endif
}
static constexpr char_type* move(char_type* dest, const char_type* src, size_t count) noexcept
{
@@ -438,8 +505,6 @@ namespace AZStd
}
static constexpr char_type* copy(char_type* dest, const char_type* src, size_t count) noexcept
{
AZ_Assert(dest != nullptr && src != nullptr, "Invalid input!");
#if az_has_builtin_memcpy
__builtin_memcpy(dest, src, count * sizeof(char_type));
#else
@@ -455,6 +520,7 @@ namespace AZStd
}
else
{
AZ_Assert(dest1 != nullptr && src1 != nullptr, "Invalid input!");
::memcpy(dest1, src1, count1 * sizeof(char_type));
}
return dest1;
@@ -7,6 +7,7 @@
*/
#pragma once
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/typetraits/conditional.h>
#include <AzCore/std/typetraits/integral_constant.h> // for true_type
@@ -58,14 +58,13 @@
# define AZSTD_IS_ABSTRACT(T) __is_abstract(T)
# define AZSTD_IS_BASE_OF(T, U) (__is_base_of(T, U) && !is_same<T, U>::value)
# define AZSTD_IS_CLASS(T) __is_class(T)
// This one doesn't quite always do the right thing:
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
# define AZSTD_IS_ENUM(T) __is_enum(T)
// This one doesn't quite always do the right thing:
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
// # define AZSTD_IS_POLYMORPHIC(T) __is_polymorphic(T)
#endif
#if defined(AZ_COMPILER_CLANG)
#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
# include <AzCore/std/typetraits/is_same.h>
# include <AzCore/std/typetraits/is_reference.h>
# include <AzCore/std/typetraits/is_volatile.h>
@@ -86,8 +85,8 @@
# define AZSTD_IS_ABSTRACT(T) __is_abstract(T)
# define AZSTD_IS_BASE_OF(T, U) (__is_base_of(T, U) && !is_same<T, U>::value)
# define AZSTD_IS_CLASS(T) __is_class(T)
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
# define AZSTD_IS_ENUM(T) __is_enum(T)
# define AZSTD_IS_CONVERTIBLE(_From, _To) AZStd::is_convertible_v<_From, _To>
# define AZSTD_IS_POLYMORPHIC(T) __is_polymorphic(T)
#endif
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
// Variadic MACROS util functions
/**
* AZ_VA_NUM_ARGS
* counts number of parameters (up to 10).
* example. AZ_VA_NUM_ARGS(x,y,z) -> expands to 3
*/
#ifndef AZ_VA_NUM_ARGS
# define AZ_VA_HAS_ARGS(...) ""#__VA_ARGS__[0] != 0
// we add the zero to avoid the case when we require at least 1 param at the end...
# define AZ_VA_NUM_ARGS(...) AZ_VA_NUM_ARGS_IMPL_((__VA_ARGS__, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
# define AZ_VA_NUM_ARGS_IMPL_(tuple) AZ_VA_NUM_ARGS_IMPL tuple
# define AZ_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, N, ...) N
// Expands a macro and calls a different macro based on the number of arguments.
//
// Example: We need to specialize a macro for 1 and 2 arguments
// #define AZ_MY_MACRO(...) AZ_MACRO_SPECIALIZE(AZ_MY_MACRO_,AZ_VA_NUM_ARGS(__VA_ARGS__),(__VA_ARGS__))
//
// #define AZ_MY_MACRO_1(_1) /* code for 1 param */
// #define AZ_MY_MACRO_2(_1,_2) /* code for 2 params */
// ... etc.
//
//
// We have 3 levels of macro expansion...
# define AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS) MACRO_NAME##NPARAMS PARAMS
# define AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS)
# define AZ_MACRO_SPECIALIZE(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS)
#endif // AZ_VA_NUM_ARGS
// Out of all supported compilers, mwerks is the only one
// that requires variadic macros to have at least 1 param.
// This is a pain they we use macros to call functions (with no params).
// we implement functions for up to 10 params
#define AZ_FUNCTION_CALL_1(_1) _1()
#define AZ_FUNCTION_CALL_2(_1, _2) _1(_2)
#define AZ_FUNCTION_CALL_3(_1, _2, _3) _1(_2, _3)
#define AZ_FUNCTION_CALL_4(_1, _2, _3, _4) _1(_2, _3, _4)
#define AZ_FUNCTION_CALL_5(_1, _2, _3, _4, _5) _1(_2, _3, _4, _5)
#define AZ_FUNCTION_CALL_6(_1, _2, _3, _4, _5, _6) _1(_2, _3, _4, _5, _6)
#define AZ_FUNCTION_CALL_7(_1, _2, _3, _4, _5, _6, _7) _1(_2, _3, _4, _5, _6, _7)
#define AZ_FUNCTION_CALL_8(_1, _2, _3, _4, _5, _6, _7, _8) _1(_2, _3, _4, _5, _6, _7, _8)
#define AZ_FUNCTION_CALL_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) _1(_2, _3, _4, _5, _6, _7, _8, _9)
#define AZ_FUNCTION_CALL_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) _1(_2, _3, _4, _5, _6, _7, _8, _9, _10)
// We require at least 1 param FunctionName
#define AZ_FUNCTION_CALL(...) AZ_MACRO_SPECIALIZE(AZ_FUNCTION_CALL_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// Based on boost macro expansion fix...
#define AZ_PREVENT_MACRO_SUBSTITUTION
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
@@ -23,7 +23,7 @@ namespace AZ
public:
virtual SystemInformation GetSystemInformation() override
{
SystemInformation result;
SystemInformation result {0, 0};
return result;
}
@@ -6,74 +6,121 @@
*
*/
#include <AzCore/Debug/StackTracer.h>
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/string/string_view.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>
namespace AZ::Debug::Platform
namespace AZ::Debug
{
#if defined(AZ_ENABLE_DEBUG_TOOLS)
bool performDebuggerDetection()
void ExceptionHandler(int signal);
#endif
constexpr int MaxMessageLength = 4096;
constexpr int MaxStackLines = 100;
namespace Platform
{
AZ::IO::SystemFile processStatusFile;
if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
#if defined(AZ_ENABLE_DEBUG_TOOLS)
bool performDebuggerDetection()
{
return false;
}
char buffer[4096];
AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
const AZStd::string_view processStatusView(buffer, buffer + numRead);
constexpr AZStd::string_view tracerPidString = "TracerPid:";
const size_t tracerPidOffset = processStatusView.find(tracerPidString);
if (tracerPidOffset == AZStd::string_view::npos)
{
return false;
}
for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
{
if (!::isspace(processStatusView[i]))
AZ::IO::SystemFile processStatusFile;
if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
{
return processStatusView[i] != '0';
return false;
}
char buffer[MaxMessageLength];
AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
const AZStd::string_view processStatusView(buffer, buffer + numRead);
constexpr AZStd::string_view tracerPidString = "TracerPid:";
const size_t tracerPidOffset = processStatusView.find(tracerPidString);
if (tracerPidOffset == AZStd::string_view::npos)
{
return false;
}
for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
{
if (processStatusView[i] != ' ')
{
return processStatusView[i] != '0';
}
}
return false;
}
bool IsDebuggerPresent()
{
static bool s_detectionPerformed = false;
static bool s_debuggerDetected = false;
if (!s_detectionPerformed)
{
s_debuggerDetected = performDebuggerDetection();
s_detectionPerformed = true;
}
return s_debuggerDetected;
}
bool AttachDebugger()
{
// Not supported yet
AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
return false;
}
void HandleExceptions(bool isEnabled)
{
if (isEnabled)
{
signal(SIGSEGV, ExceptionHandler);
signal(SIGTRAP, ExceptionHandler);
signal(SIGILL, ExceptionHandler);
}
else
{
signal(SIGSEGV, SIG_DFL);
signal(SIGTRAP, SIG_DFL);
signal(SIGILL, SIG_DFL);
}
}
return false;
}
bool IsDebuggerPresent()
{
static bool s_detectionPerformed = false;
static bool s_debuggerDetected = false;
if (!s_detectionPerformed)
void DebugBreak()
{
s_debuggerDetected = performDebuggerDetection();
s_detectionPerformed = true;
raise(SIGINT);
}
return s_debuggerDetected;
}
bool AttachDebugger()
{
// Not supported yet
AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
return false;
}
void HandleExceptions(bool)
{}
void DebugBreak()
{
raise(SIGINT);
}
#endif // AZ_ENABLE_DEBUG_TOOLS
void Terminate(int exitCode)
void Terminate(int exitCode)
{
_exit(exitCode);
}
} // namespace Platform
#if defined(AZ_ENABLE_DEBUG_TOOLS)
void ExceptionHandler(int signal)
{
_exit(exitCode);
char message[MaxMessageLength];
// Trace::RawOutput
Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal));
Debug::Trace::Instance().RawOutput(nullptr, message);
StackFrame frames[MaxStackLines];
SymbolStorage::StackLine stackLines[MaxStackLines];
SymbolStorage decoder;
const unsigned int numberOfFrames = StackRecorder::Record(frames, MaxStackLines);
decoder.DecodeFrames(frames, numberOfFrames, stackLines);
for (int i = 0; i < numberOfFrames; ++i)
{
azsnprintf(message, MaxMessageLength, "%s \n", stackLines[i]);
Debug::Trace::Instance().RawOutput(nullptr, message);
}
Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
}
} // namespace AZ::Debug::Platform
#endif
} // namespace AZ::Debug
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
@@ -16,6 +16,7 @@ set(LY_BUILD_DEPENDENCIES
PRIVATE
pthread
3rdParty::unwind
dl
atomic
PUBLIC
${CMAKE_DL_LIBS}
)
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 0
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1
#define AZ_TRAIT_USE_WINDOWS_FILE_API 1
@@ -99,7 +99,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
+27 -27
View File
@@ -19,6 +19,7 @@
#include <AzCore/std/string/regex.h>
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/std/typetraits/is_convertible.h>
// we need this for AZ_TEST_FLOAT compare
#include <cinttypes>
@@ -1458,34 +1459,33 @@ namespace UnitTest
using ValidFormatArg = AZStd::string::_Format_Internal::ValidFormatArg;
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v1), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v2), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v3), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v4), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v5), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v6), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v7), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v8), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v9), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v10), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v11), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v12), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v13), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v14), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v15), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v16), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v17), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v18), ValidFormatArg), "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v1), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v2), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v3), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v4), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v5), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v7), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v8), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v9), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v10), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v11), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v12), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v13), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v14), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v15), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v16), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v17), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v18), ValidFormatArg>, "Should be valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::string, ValidFormatArg), "AZStd::string shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::string, ValidFormatArg), "std::string shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::wstring, ValidFormatArg), "AZStd::wstring shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::wstring, ValidFormatArg), "std::wstring shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(WrappedInt, ValidFormatArg), "WrappedInt shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::string_view, ValidFormatArg), "AZStd::string_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::wstring_view, ValidFormatArg), "AZStd::wstring_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::string_view, ValidFormatArg), "string_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::wstring_view, ValidFormatArg), "wstring_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::string, ValidFormatArg>, "AZStd::string shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::string, ValidFormatArg>, "std::string shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::wstring, ValidFormatArg>, "AZStd::wstring shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::wstring, ValidFormatArg>, "std::wstring shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<WrappedInt, ValidFormatArg>, "WrappedInt shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::string_view, ValidFormatArg>, "AZStd::string_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::wstring_view, ValidFormatArg>, "AZStd::wstring_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::string_view, ValidFormatArg>, "string_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::wstring_view, ValidFormatArg>, "wstring_view shouldn't be a valid format argument");
}
TEST_F(String, StringViewPrintf)
@@ -0,0 +1,189 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/DOM/DomValue.h>
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <Tests/DOM/DomFixtures.h>
namespace AZ::Dom::Tests
{
void DomTestHarness::SetUpHarness()
{
NameDictionary::Create();
AZ::AllocatorInstance<ValueAllocator>::Create();
}
void DomTestHarness::TearDownHarness()
{
AZ::AllocatorInstance<ValueAllocator>::Destroy();
NameDictionary::Destroy();
}
void DomBenchmarkFixture::SetUp(const ::benchmark::State& st)
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
SetUpHarness();
}
void DomBenchmarkFixture::SetUp(::benchmark::State& st)
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
SetUpHarness();
}
void DomBenchmarkFixture::TearDown(::benchmark::State& st)
{
TearDownHarness();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
void DomBenchmarkFixture::TearDown(const ::benchmark::State& st)
{
TearDownHarness();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
rapidjson::Document DomBenchmarkFixture::GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength)
{
rapidjson::Document document;
document.SetObject();
AZStd::string entryTemplate;
while (entryTemplate.size() < aznumeric_cast<size_t>(stringTemplateLength))
{
entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
}
entryTemplate.resize(stringTemplateLength);
AZStd::string buffer;
auto createString = [&](int n) -> rapidjson::Value
{
buffer = AZStd::string::format("#%i %s", n, entryTemplate.c_str());
return rapidjson::Value(buffer.data(), aznumeric_cast<rapidjson::SizeType>(buffer.size()), document.GetAllocator());
};
auto createEntry = [&](int n) -> rapidjson::Value
{
rapidjson::Value entry(rapidjson::kObjectType);
entry.AddMember("string", createString(n), document.GetAllocator());
entry.AddMember("int", rapidjson::Value(n), document.GetAllocator());
entry.AddMember("double", rapidjson::Value(aznumeric_cast<double>(n) * 0.5), document.GetAllocator());
entry.AddMember("bool", rapidjson::Value(n % 2 == 0), document.GetAllocator());
entry.AddMember("null", rapidjson::Value(rapidjson::kNullType), document.GetAllocator());
return entry;
};
auto createArray = [&]() -> rapidjson::Value
{
rapidjson::Value array;
array.SetArray();
for (int i = 0; i < entryCount; ++i)
{
array.PushBack(createEntry(i), document.GetAllocator());
}
return array;
};
auto createObject = [&]() -> rapidjson::Value
{
rapidjson::Value object;
object.SetObject();
for (int i = 0; i < entryCount; ++i)
{
buffer = AZStd::string::format("Key%i", i);
rapidjson::Value key;
key.SetString(buffer.data(), aznumeric_cast<rapidjson::SizeType>(buffer.length()), document.GetAllocator());
object.AddMember(key.Move(), createArray(), document.GetAllocator());
}
return object;
};
document.SetObject();
document.AddMember("entries", createObject(), document.GetAllocator());
return document;
}
AZStd::string DomBenchmarkFixture::GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
{
rapidjson::Document document = GenerateDomJsonBenchmarkDocument(entryCount, stringTemplateLength);
AZStd::string serializedJson;
auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson);
AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON");
return serializedJson;
}
Value DomBenchmarkFixture::GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
{
Value root(Type::Object);
AZStd::string entryTemplate;
while (entryTemplate.size() < aznumeric_cast<size_t>(stringTemplateLength))
{
entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
}
entryTemplate.resize(stringTemplateLength);
AZStd::string buffer;
auto createString = [&](int n) -> Value
{
return Value(AZStd::string::format("#%i %s", n, entryTemplate.c_str()), true);
};
auto createEntry = [&](int n) -> Value
{
Value entry(Type::Object);
entry.AddMember("string", createString(n));
entry.AddMember("int", Value(n));
entry.AddMember("double", Value(aznumeric_cast<double>(n) * 0.5));
entry.AddMember("bool", Value(n % 2 == 0));
entry.AddMember("null", Value(Type::Null));
return entry;
};
auto createArray = [&]() -> Value
{
Value array(Type::Array);
for (int i = 0; i < entryCount; ++i)
{
array.ArrayPushBack(createEntry(i));
}
return array;
};
auto createObject = [&]() -> Value
{
Value object;
object.SetObject();
for (int i = 0; i < entryCount; ++i)
{
buffer = AZStd::string::format("Key%i", i);
object.AddMember(AZ::Name(buffer), createArray());
}
return object;
};
root["entries"] = createObject();
return root;
}
void DomTestFixture::SetUp()
{
UnitTest::AllocatorsFixture::SetUp();
SetUpHarness();
}
void DomTestFixture::TearDown()
{
TearDownHarness();
UnitTest::AllocatorsFixture::TearDown();
}
} // namespace AZ::Dom::Tests
@@ -0,0 +1,66 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/DOM/DomUtils.h>
#include <AzCore/JSON/document.h>
#include <AzCore/UnitTest/TestTypes.h>
#define DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method)->Args({ 10, 5 })->Args({ 10, 500 })->Args({ 100, 5 })->Args({ 100, 500 })
#define DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(BaseClass, Method) \
DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method)->Unit(benchmark::kMillisecond);
#define DOM_REGISTER_SERIALIZATION_BENCHMARK_NS(BaseClass, Method) \
DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method)->Unit(benchmark::kNanosecond);
namespace AZ::Dom::Tests
{
class DomTestHarness
{
public:
virtual ~DomTestHarness() = default;
virtual void SetUpHarness();
virtual void TearDownHarness();
};
class DomBenchmarkFixture
: public DomTestHarness
, public UnitTest::AllocatorsBenchmarkFixture
{
public:
void SetUp(const ::benchmark::State& st) override;
void SetUp(::benchmark::State& st) override;
void TearDown(::benchmark::State& st) override;
void TearDown(const ::benchmark::State& st) override;
rapidjson::Document GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength);
AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength);
Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength);
template<class T>
static void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state)
{
{
T instance = AZStd::move(value);
state.PauseTiming();
}
state.ResumeTiming();
}
};
class DomTestFixture
: public DomTestHarness
, public UnitTest::AllocatorsFixture
{
public:
void SetUp() override;
void TearDown() override;
};
} // namespace AZ::Dom::Tests
@@ -16,131 +16,14 @@
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <Tests/DOM/DomFixtures.h>
namespace Benchmark
namespace AZ::Dom::Benchmark
{
class DomJsonBenchmark : public UnitTest::AllocatorsBenchmarkFixture
class DomJsonBenchmark : public Tests::DomBenchmarkFixture
{
public:
void SetUp(const ::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
AZ::AllocatorInstance<AZ::Dom::ValueAllocator>::Create();
}
void SetUp(::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
AZ::AllocatorInstance<AZ::Dom::ValueAllocator>::Create();
}
void TearDown(::benchmark::State& st) override
{
AZ::AllocatorInstance<AZ::Dom::ValueAllocator>::Destroy();
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
void TearDown(const ::benchmark::State& st) override
{
AZ::AllocatorInstance<AZ::Dom::ValueAllocator>::Destroy();
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
rapidjson::Document GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength)
{
rapidjson::Document document;
document.SetObject();
AZStd::string entryTemplate;
while (entryTemplate.size() < static_cast<size_t>(stringTemplateLength))
{
entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
}
entryTemplate.resize(stringTemplateLength);
AZStd::string buffer;
auto createString = [&](int n) -> rapidjson::Value
{
buffer = AZStd::string::format("#%i %s", n, entryTemplate.c_str());
return rapidjson::Value(buffer.data(), static_cast<rapidjson::SizeType>(buffer.size()), document.GetAllocator());
};
auto createEntry = [&](int n) -> rapidjson::Value
{
rapidjson::Value entry(rapidjson::kObjectType);
entry.AddMember("string", createString(n), document.GetAllocator());
entry.AddMember("int", rapidjson::Value(n), document.GetAllocator());
entry.AddMember("double", rapidjson::Value(static_cast<double>(n) * 0.5), document.GetAllocator());
entry.AddMember("bool", rapidjson::Value(n % 2 == 0), document.GetAllocator());
entry.AddMember("null", rapidjson::Value(rapidjson::kNullType), document.GetAllocator());
return entry;
};
auto createArray = [&]() -> rapidjson::Value
{
rapidjson::Value array;
array.SetArray();
for (int i = 0; i < entryCount; ++i)
{
array.PushBack(createEntry(i), document.GetAllocator());
}
return array;
};
auto createObject = [&]() -> rapidjson::Value
{
rapidjson::Value object;
object.SetObject();
for (int i = 0; i < entryCount; ++i)
{
buffer = AZStd::string::format("Key%i", i);
rapidjson::Value key;
key.SetString(buffer.data(), static_cast<rapidjson::SizeType>(buffer.length()), document.GetAllocator());
object.AddMember(key.Move(), createArray(), document.GetAllocator());
}
return object;
};
document.SetObject();
document.AddMember("entries", createObject(), document.GetAllocator());
return document;
}
AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
{
rapidjson::Document document = GenerateDomJsonBenchmarkDocument(entryCount, stringTemplateLength);
AZStd::string serializedJson;
auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson);
AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON");
return serializedJson;
}
template <class T>
void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state)
{
{
T instance = AZStd::move(value);
state.PauseTiming();
}
state.ResumeTiming();
}
};
// Helper macro for registering JSON benchmarks
#define BENCHMARK_REGISTER_JSON(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method) \
->Args({ 10, 5 }) \
->Args({ 10, 500 }) \
->Args({ 100, 5 }) \
->Args({ 100, 500 }) \
->Unit(benchmark::kMillisecond);
BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace)(benchmark::State& state)
{
AZ::Dom::JsonBackend backend;
@@ -163,7 +46,7 @@ namespace Benchmark
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace)
BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace)(benchmark::State& state)
{
@@ -187,7 +70,7 @@ namespace Benchmark
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace)
BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjson)(benchmark::State& state)
{
@@ -207,7 +90,7 @@ namespace Benchmark
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjson)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToRapidjson)
BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValue)(benchmark::State& state)
{
@@ -227,7 +110,7 @@ namespace Benchmark
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValue)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToAzDomValue)
BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonDeserializeToRapidjson)(benchmark::State& state)
{
@@ -243,7 +126,7 @@ namespace Benchmark
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeserializeToRapidjson)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonDeserializeToRapidjson)
BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonMakeComplexObject)(benchmark::State& state)
{
@@ -254,7 +137,7 @@ namespace Benchmark
state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonMakeComplexObject)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonMakeComplexObject)
BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonLookupMemberByString)(benchmark::State& state)
{
@@ -264,7 +147,9 @@ namespace Benchmark
{
AZStd::string key(AZStd::string::format("key%" PRId64, i));
keys.push_back(key);
document.AddMember(rapidjson::Value(key.data(), static_cast<rapidjson::SizeType>(key.size()), document.GetAllocator()), rapidjson::Value(i), document.GetAllocator());
document.AddMember(
rapidjson::Value(key.data(), static_cast<rapidjson::SizeType>(key.size()), document.GetAllocator()), rapidjson::Value(i),
document.GetAllocator());
}
for (auto _ : state)
@@ -293,7 +178,7 @@ namespace Benchmark
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeepCopy)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonDeepCopy)
BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonCopyAndMutate)(benchmark::State& state)
{
@@ -309,9 +194,8 @@ namespace Benchmark
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonCopyAndMutate)
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonCopyAndMutate)
#undef BENCHMARK_REGISTER_JSON
} // namespace Benchmark
} // namespace AZ::Dom::Benchmark
#endif // defined(HAVE_BENCHMARK)
@@ -13,24 +13,23 @@
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <Tests/DOM/DomFixtures.h>
namespace AZ::Dom::Tests
{
class DomJsonTests : public UnitTest::AllocatorsFixture
class DomJsonTests : public DomTestFixture
{
public:
void SetUp() override
{
UnitTest::AllocatorsFixture::SetUp();
NameDictionary::Create();
DomTestFixture::SetUp();
m_document = AZStd::make_unique<rapidjson::Document>();
}
void TearDown() override
{
m_document.reset();
NameDictionary::Destroy();
UnitTest::AllocatorsFixture::TearDown();
DomTestFixture::TearDown();
}
rapidjson::Value CreateString(const AZStd::string& text)
@@ -0,0 +1,99 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Tests/DOM/DomFixtures.h>
#include <AzCore/DOM/DomPath.h>
namespace AZ::Dom::Benchmark
{
using DomPathBenchmark = Tests::DomBenchmarkFixture;
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPath_Concatenate_InPlace)(benchmark::State& state)
{
AZ::Name entry1("entry1");
AZ::Name entry2("entry2");
PathEntry end;
end.SetEndOfArray();
for (auto _ : state)
{
Path p;
p /= entry1;
p /= entry2;
p /= 0;
p /= end;
}
state.SetItemsProcessed(4 * state.iterations());
}
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPath_Concatenate_InPlace);
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPath_Concatenate_Copy)(benchmark::State& state)
{
AZ::Name entry1("entry1");
AZ::Name entry2("entry2");
PathEntry end;
end.SetEndOfArray();
for (auto _ : state)
{
Path p = Path() / entry1 / entry2 / 0 / end;
}
state.SetItemsProcessed(4 * state.iterations());
}
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPath_Concatenate_Copy);
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPath_ToString)(benchmark::State& state)
{
Path p("/path/with/multiple/0/different/components/65536/999/-");
AZStd::string s;
s.resize_no_construct(p.GetStringLength());
for (auto _ : state)
{
p.GetStringLength();
p.FormatString(s.data(), s.size());
}
state.SetBytesProcessed(s.size() * state.iterations());
}
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPath_ToString);
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPath_FromString)(benchmark::State& state)
{
AZStd::string pathString = "/path/with/multiple/0/different/components/including-long-strings-like-this/65536/999/-";
for (auto _ : state)
{
Path p(pathString);
benchmark::DoNotOptimize(p);
}
state.SetBytesProcessed(pathString.size() * state.iterations());
}
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPath_FromString);
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPathEntry_IsEndOfArray)(benchmark::State& state)
{
PathEntry name("name");
PathEntry index(0);
PathEntry endOfArray;
endOfArray.SetEndOfArray();
for (auto _ : state)
{
name.IsEndOfArray();
index.IsEndOfArray();
endOfArray.IsEndOfArray();
}
state.SetItemsProcessed(3 * state.iterations());
}
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPathEntry_IsEndOfArray);
}
@@ -0,0 +1,177 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/DOM/DomPath.h>
#include <AzCore/Name/NameDictionary.h>
#include <Tests/DOM/DomFixtures.h>
namespace AZ::Dom::Tests
{
class DomPathTests : public DomTestFixture
{
};
TEST_F(DomPathTests, EmptyPath_IsEmpty)
{
Path path("");
EXPECT_EQ(path.GetEntries().size(), 0);
}
TEST_F(DomPathTests, EmptyPath_IsEqualToDefault)
{
EXPECT_EQ(Path(""), Path());
}
TEST_F(DomPathTests, Index_IsNumeric)
{
EXPECT_EQ(Path("/0")[0], 0);
EXPECT_EQ(Path("/20")[0], 20);
EXPECT_EQ(Path("/9999")[0], 9999);
EXPECT_EQ(Path("/0/4/5/1")[3], 1);
}
TEST_F(DomPathTests, Index_ConvertsToString)
{
Path p;
EXPECT_EQ(p.ToString(), "");
p.Push(0);
EXPECT_EQ(p.ToString(), "/0");
p.Push(1);
EXPECT_EQ(p.ToString(), "/0/1");
p.Push(10);
EXPECT_EQ(p.ToString(), "/0/1/10");
p.Push(9999);
EXPECT_EQ(p.ToString(), "/0/1/10/9999");
p.Pop();
EXPECT_EQ(p.ToString(), "/0/1/10");
}
TEST_F(DomPathTests, Key_IsString)
{
EXPECT_EQ(Path("/foo")[0], "foo");
EXPECT_EQ(Path("/bar")[0], "bar");
EXPECT_EQ(Path("/foo/bar/baz12345")[0], "foo");
EXPECT_EQ(Path("/foo/bar/baz12345")[2], "baz12345");
EXPECT_EQ(Path("//foo")[0], "");
}
TEST_F(DomPathTests, Key_ConvertsToString)
{
Path p;
p.Push("foo");
EXPECT_EQ(p.ToString(), "/foo");
p.Push("bar");
EXPECT_EQ(p.ToString(), "/foo/bar");
p.Push("another_key");
EXPECT_EQ(p.ToString(), "/foo/bar/another_key");
p.Pop();
EXPECT_EQ(p.ToString(), "/foo/bar");
}
TEST_F(DomPathTests, Key_ConvertsFromEscaped)
{
EXPECT_EQ(Path("/foo~0")[0], "foo~");
EXPECT_EQ(Path("/foo~0bar~0~0")[0], "foo~bar~~");
EXPECT_EQ(Path("/foo~1bar/baz")[0], "foo/bar");
EXPECT_EQ(Path("/~1foo~1")[0], "/foo/");
}
TEST_F(DomPathTests, Key_ConvertsToEscaped)
{
Path p;
p.Push("with~tilde");
EXPECT_EQ(p.ToString(), "/with~0tilde");
p.Push("with/slash");
EXPECT_EQ(p.ToString(), "/with~0tilde/with~1slash");
p.Clear();
p.Push("/~with/mixed/characters~");
EXPECT_EQ(p.ToString(), "/~1~0with~1mixed~1characters~0");
}
TEST_F(DomPathTests, MixedPath_Resolves)
{
EXPECT_EQ(Path("/foo/0")[0], "foo");
EXPECT_EQ(Path("/foo/0")[1], 0);
EXPECT_EQ(Path("/42/foo/bar/0")[0], 42);
EXPECT_EQ(Path("/42/foo/bar/0")[1], "foo");
EXPECT_EQ(Path("/42/foo/bar/0")[2], "bar");
EXPECT_EQ(Path("/42/foo/bar/0")[3], 0);
}
TEST_F(DomPathTests, MixedPath_ConvertsToString)
{
Path p;
p.Push("foo");
EXPECT_EQ(p.ToString(), "/foo");
p.Push(0);
EXPECT_EQ(p.ToString(), "/foo/0");
p.Push("another_key");
EXPECT_EQ(p.ToString(), "/foo/0/another_key");
p.Push(100);
EXPECT_EQ(p.ToString(), "/foo/0/another_key/100");
p.Pop();
EXPECT_EQ(p.ToString(), "/foo/0/another_key");
}
TEST_F(DomPathTests, OperatorOverloads_Append)
{
EXPECT_EQ(Path("/foo/bar"), Path("/foo") / Path("/bar"));
EXPECT_EQ(Path("/foo"), Path("/foo") / Path());
EXPECT_EQ(Path("/foo/1/bar/0"), Path("/foo/1") / Path("/bar/0"));
EXPECT_EQ(Path("/foo") / 0, Path("/foo/0"));
EXPECT_EQ(Path() / "foo" / "bar", Path("/foo/bar"));
EXPECT_EQ(Path("/foo") / "bar" / "baz", Path("/foo/bar/baz"));
Path p("/foo/bar");
p /= "baz";
EXPECT_EQ(p, Path("/foo/bar/baz"));
p /= Path("0/1");
EXPECT_EQ(p, Path("/foo/bar/baz/0/1"));
}
TEST_F(DomPathTests, EndOfArray_FromString)
{
EXPECT_FALSE(Path("/foo/-")[0].IsEndOfArray());
EXPECT_TRUE(Path("/foo/-")[1].IsEndOfArray());
EXPECT_TRUE(Path("/foo/-/-")[2].IsEndOfArray());
}
TEST_F(DomPathTests, EndOfArray_ToString)
{
EXPECT_EQ(Path("/-").ToString(), "/-");
EXPECT_EQ(Path("/0/-").ToString(), "/0/-");
}
TEST_F(DomPathTests, MixedPath_AppendToString)
{
Path p("/foo/0");
AZStd::string s;
p.AppendToString(s);
EXPECT_EQ(s, "/foo/0");
p.AppendToString(s);
EXPECT_EQ(s, "/foo/0/foo/0");
}
} // namespace AZ::Dom::Tests
@@ -6,111 +6,134 @@
*
*/
#include <AzCore/DOM/DomValue.h>
#include <AzCore/DOM/DomUtils.h>
#include <AzCore/DOM/DomValue.h>
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <cinttypes>
#include <Tests/DOM/DomFixtures.h>
namespace AZ::Dom::Benchmark
{
class DomValueBenchmark : public UnitTest::AllocatorsBenchmarkFixture
class DomValueBenchmark : public Tests::DomBenchmarkFixture
{
public:
void SetUp(const ::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
AZ::AllocatorInstance<ValueAllocator>::Create();
}
void SetUp(::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
AZ::AllocatorInstance<ValueAllocator>::Create();
}
void TearDown(::benchmark::State& st) override
{
AZ::AllocatorInstance<ValueAllocator>::Destroy();
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
void TearDown(const ::benchmark::State& st) override
{
AZ::AllocatorInstance<ValueAllocator>::Destroy();
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
{
Value root(Type::Object);
AZStd::string entryTemplate;
while (entryTemplate.size() < static_cast<size_t>(stringTemplateLength))
{
entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
}
entryTemplate.resize(stringTemplateLength);
AZStd::string buffer;
auto createString = [&](int n) -> Value
{
return Value(AZStd::string::format("#%i %s", n, entryTemplate.c_str()), true);
};
auto createEntry = [&](int n) -> Value
{
Value entry(Type::Object);
entry.AddMember("string", createString(n));
entry.AddMember("int", Value(n));
entry.AddMember("double", Value(static_cast<double>(n) * 0.5));
entry.AddMember("bool", Value(n % 2 == 0));
entry.AddMember("null", Value(Type::Null));
return entry;
};
auto createArray = [&]() -> Value
{
Value array(Type::Array);
for (int i = 0; i < entryCount; ++i)
{
array.ArrayPushBack(createEntry(i));
}
return array;
};
auto createObject = [&]() -> Value
{
Value object;
object.SetObject();
for (int i = 0; i < entryCount; ++i)
{
buffer = AZStd::string::format("Key%i", i);
object.AddMember(AZ::Name(buffer), createArray());
}
return object;
};
root["entries"] = createObject();
return root;
}
template<class T>
void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state)
{
{
T instance = AZStd::move(value);
state.PauseTiming();
}
state.ResumeTiming();
}
};
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueGetType_UsingVariantIndex)(benchmark::State& state)
{
Value intValue(5);
Value boolValue(true);
Value objValue(Type::Object);
Value nodeValue(Type::Node);
Value arrValue(Type::Array);
Value uintValue(5u);
Value doubleValue(4.0);
Value stringValue("foo", true);
for (auto _ : state)
{
(intValue.GetType());
(boolValue.GetType());
(objValue.GetType());
(nodeValue.GetType());
(arrValue.GetType());
(uintValue.GetType());
(doubleValue.GetType());
(stringValue.GetType());
}
state.SetItemsProcessed(8 * state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueGetType_UsingVariantIndex);
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueGetType_UsingVariantVisit)(benchmark::State& state)
{
Value intValue(5);
Value boolValue(true);
Value objValue(Type::Object);
Value nodeValue(Type::Node);
Value arrValue(Type::Array);
Value uintValue(5u);
Value doubleValue(4.0);
Value stringValue("foo", true);
auto getTypeViaVisit = [](const Value& value)
{
return AZStd::visit(
[](auto&& value) constexpr -> Type
{
using CurrentType = AZStd::decay_t<decltype(value)>;
if constexpr (AZStd::is_same_v<CurrentType, AZStd::monostate>)
{
return Type::Null;
}
else if constexpr (AZStd::is_same_v<CurrentType, int64_t>)
{
return Type::Int64;
}
else if constexpr (AZStd::is_same_v<CurrentType, uint64_t>)
{
return Type::Uint64;
}
else if constexpr (AZStd::is_same_v<CurrentType, double>)
{
return Type::Double;
}
else if constexpr (AZStd::is_same_v<CurrentType, bool>)
{
return Type::Bool;
}
else if constexpr (AZStd::is_same_v<CurrentType, AZStd::string_view>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, Value::SharedStringType>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, Value::ShortStringType>)
{
return Type::String;
}
else if constexpr (AZStd::is_same_v<CurrentType, ObjectPtr>)
{
return Type::Object;
}
else if constexpr (AZStd::is_same_v<CurrentType, ArrayPtr>)
{
return Type::Array;
}
else if constexpr (AZStd::is_same_v<CurrentType, NodePtr>)
{
return Type::Node;
}
else if constexpr (AZStd::is_same_v<CurrentType, Value::OpaqueStorageType>)
{
return Type::Opaque;
}
else
{
AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type");
}
},
value.GetInternalValue());
};
for (auto _ : state)
{
(getTypeViaVisit(intValue));
(getTypeViaVisit(boolValue));
(getTypeViaVisit(objValue));
(getTypeViaVisit(nodeValue));
(getTypeViaVisit(arrValue));
(getTypeViaVisit(uintValue));
(getTypeViaVisit(doubleValue));
(getTypeViaVisit(stringValue));
}
state.SetItemsProcessed(8 * state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueGetType_UsingVariantVisit);
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueMakeComplexObject)(benchmark::State& state)
{
for (auto _ : state)
@@ -120,12 +143,7 @@ namespace AZ::Dom::Benchmark
state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueMakeComplexObject)
->Args({ 10, 5 })
->Args({ 10, 500 })
->Args({ 100, 5 })
->Args({ 100, 500 })
->Unit(benchmark::kMillisecond);
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueMakeComplexObject)
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueShallowCopy)(benchmark::State& state)
{
@@ -139,12 +157,7 @@ namespace AZ::Dom::Benchmark
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueShallowCopy)
->Args({ 10, 5 })
->Args({ 10, 500 })
->Args({ 100, 5 })
->Args({ 100, 500 })
->Unit(benchmark::kNanosecond);
DOM_REGISTER_SERIALIZATION_BENCHMARK_NS(DomValueBenchmark, AzDomValueShallowCopy)
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueCopyAndMutate)(benchmark::State& state)
{
@@ -159,12 +172,7 @@ namespace AZ::Dom::Benchmark
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueCopyAndMutate)
->Args({ 10, 5 })
->Args({ 10, 500 })
->Args({ 100, 5 })
->Args({ 100, 500 })
->Unit(benchmark::kNanosecond);
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueCopyAndMutate)
BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueDeepCopy)(benchmark::State& state)
{
@@ -178,12 +186,7 @@ namespace AZ::Dom::Benchmark
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueDeepCopy)
->Args({ 10, 5 })
->Args({ 10, 500 })
->Args({ 100, 5 })
->Args({ 100, 500 })
->Unit(benchmark::kMillisecond);
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueDeepCopy)
BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByName)(benchmark::State& state)
{
@@ -15,26 +15,18 @@
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/numeric.h>
#include <Tests/DOM/DomFixtures.h>
namespace AZ::Dom::Tests
{
class DomValueTests : public UnitTest::AllocatorsFixture
class DomValueTests : public DomTestFixture
{
public:
void SetUp() override
{
UnitTest::AllocatorsFixture::SetUp();
NameDictionary::Create();
AZ::AllocatorInstance<ValueAllocator>::Create();
}
void TearDown() override
{
m_value = Value();
AZ::AllocatorInstance<ValueAllocator>::Destroy();
NameDictionary::Destroy();
UnitTest::AllocatorsFixture::TearDown();
DomTestFixture::TearDown();
}
void PerformValueChecks()
+15 -15
View File
@@ -373,8 +373,8 @@ namespace UnitTest
: public AllocatorsFixture
{
public:
using Handler = Handler<Bus>;
using MultiHandlerById = MultiHandlerById<Bus>;
using BusHandler = Handler<Bus>;
using BusMultiHandlerById = MultiHandlerById<Bus>;
EBusTestAll()
{
@@ -402,7 +402,7 @@ namespace UnitTest
{
for (int handler = 0; handler < numHandlersPerAddress; ++handler)
{
m_handlers[address].emplace_back(aznew Handler(address, connectOnConstruct));
m_handlers[address].emplace_back(aznew BusHandler(address, connectOnConstruct));
++m_numHandlers;
}
}
@@ -429,7 +429,7 @@ namespace UnitTest
{
for (const auto& handlerPair : m_handlers)
{
for (Handler* handler : handlerPair.second)
for (BusHandler* handler : handlerPair.second)
{
delete handler;
}
@@ -452,7 +452,7 @@ namespace UnitTest
if (AddressesAreOrdered())
{
// Collect the first handler from each address
using PairType = AZStd::pair<int, Handler*>;
using PairType = AZStd::pair<int, BusHandler*>;
AZStd::vector<PairType> sortedHandlers;
for (const auto& handlerPair : m_handlers)
{
@@ -495,7 +495,7 @@ namespace UnitTest
{
auto& handlers = m_handlers[id];
for (Handler* handler : handlers)
for (BusHandler* handler : handlers)
{
EXPECT_EQ(expected, handler->m_eventCalls);
}
@@ -505,11 +505,11 @@ namespace UnitTest
{
// Sort the handlers the same way we expect the bus to sort them
auto sortedHandlers = handlers;
AZStd::sort(sortedHandlers.begin(), sortedHandlers.end(), AZStd::bind(&Handler::Compare, AZStd::placeholders::_1, AZStd::placeholders::_2));
AZStd::sort(sortedHandlers.begin(), sortedHandlers.end(), AZStd::bind(&BusHandler::Compare, AZStd::placeholders::_1, AZStd::placeholders::_2));
// Iterate over the list, and validate that they were called in the correct order
unsigned int lastExecuted = 0;
for (const Handler* handler : sortedHandlers)
for (const BusHandler* handler : sortedHandlers)
{
if (lastExecuted > 0)
{
@@ -550,7 +550,7 @@ namespace UnitTest
}
protected:
AZStd::unordered_map<int, AZStd::vector<Handler*>> m_handlers;
AZStd::unordered_map<int, AZStd::vector<BusHandler*>> m_handlers;
int m_numHandlers = 0;
};
TYPED_TEST_CASE(EBusTestAll, BusTypesAll);
@@ -578,7 +578,7 @@ namespace UnitTest
TYPED_TEST(EBusTestAll, ConnectDisconnect)
{
using Bus = TypeParam;
using Handler = typename EBusTestAll<Bus>::Handler;
using Handler = typename EBusTestAll<Bus>::BusHandler;
constexpr bool connectOnConstruct{ true };
Handler meh(0, connectOnConstruct);
@@ -602,13 +602,13 @@ namespace UnitTest
TYPED_TEST(EBusTestIdMultiHandlers, EnumerateHandlers_MultiHandler)
{
using Bus = TypeParam;
using MultiHandlerById = typename EBusTestAll<Bus>::MultiHandlerById;
using BusMultiHandlerById = typename EBusTestAll<Bus>::BusMultiHandlerById;
MultiHandlerById sourceMultiHandler{ 0, 1, 2 };
MultiHandlerById multiHandlerWithOverlappingIds{ 1, 3, 5 };
BusMultiHandlerById sourceMultiHandler{ 0, 1, 2 };
BusMultiHandlerById multiHandlerWithOverlappingIds{ 1, 3, 5 };
// Test handlers' enumeration functionality
Bus::EnumerateHandlers([](typename MultiHandlerById::Interface* interfaceInst) -> bool
Bus::EnumerateHandlers([](typename BusMultiHandlerById::Interface* interfaceInst) -> bool
{
interfaceInst->OnEvent();
return true;
@@ -618,7 +618,7 @@ namespace UnitTest
TYPED_TEST(EBusTestId, FindFirstHandler)
{
using Bus = TypeParam;
using Handler = typename EBusTestAll<Bus>::Handler;
using Handler = typename EBusTestAll<Bus>::BusHandler;
constexpr bool connectOnConstruct{ true };
Handler meh0(0, connectOnConstruct); /// <-- Bind to bus 0
Handler meh1(1, connectOnConstruct); /// <-- Bind to bus 1
+11 -6
View File
@@ -4014,9 +4014,12 @@ TEST_F(SerializeBasicTest, BasicTypeTest_Succeed)
};
}
} // namespace UnitTest
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnum, "{4AF433C2-055E-4E34-921A-A7D16AB548CA}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnumClass, "{4FEC2F0B-A599-4FCD-836B-89E066791793}");
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnum, "{4AF433C2-055E-4E34-921A-A7D16AB548CA}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnumClass, "{4FEC2F0B-A599-4FCD-836B-89E066791793}");
}
namespace UnitTest
{
@@ -7798,10 +7801,12 @@ namespace UnitTest
};
}
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnscopedSerializationEnum, "{83383BFA-F6DA-4124-BE4F-2FAAB7C594E7}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestScopedSerializationEnum, "{17341C5E-81C3-44CB-A40D-F97D49C2531D}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnsignedEnum, "{0F91A5AE-DADA-4455-B158-8DB79D277495}");
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnscopedSerializationEnum, "{83383BFA-F6DA-4124-BE4F-2FAAB7C594E7}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestScopedSerializationEnum, "{17341C5E-81C3-44CB-A40D-F97D49C2531D}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnsignedEnum, "{0F91A5AE-DADA-4455-B158-8DB79D277495}");
}
namespace UnitTest
{
@@ -215,8 +215,12 @@ set(FILES
AZStd/Variant.cpp
AZStd/VariantSerialization.cpp
AZStd/VectorAndArray.cpp
DOM/DomFixtures.cpp
DOM/DomFixtures.h
DOM/DomJsonTests.cpp
DOM/DomJsonBenchmarks.cpp
DOM/DomPathTests.cpp
DOM/DomPathBenchmarks.cpp
DOM/DomValueTests.cpp
DOM/DomValueBenchmarks.cpp
)
@@ -489,6 +489,21 @@ namespace AzFramework
//=========================================================================
void AssetCatalog::EnumerateAssets(BeginAssetEnumerationCB beginCB, AssetEnumerationCB enumerateCB, EndAssetEnumerationCB endCB)
{
using AssetCatalogRequestBusContext = typename AZ::Data::AssetCatalogRequestBus::Context;
// Setting trackCallstack to true causes the context mutex to attempt to re-lock.
// That is being avoided here as the code only wants to unlock the Context mutex if it is in a dispatch.
constexpr bool trackCallstack = false;
AssetCatalogRequestBusContext* assetCatalogContext = AZ::Data::AssetCatalogRequestBus::GetContext(trackCallstack);
bool hasAssetCatalogMutex = false;
if (assetCatalogContext != nullptr && AZ::Data::AssetCatalogRequestBus::IsInDispatchThisThread(assetCatalogContext))
{
hasAssetCatalogMutex = true;
// Unlock the dispatch mutex for the AssetCatalogRequestBus
assetCatalogContext->m_contextMutex.unlock();
}
if (beginCB)
{
beginCB();
@@ -496,9 +511,13 @@ namespace AzFramework
if (enumerateCB)
{
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_registryMutex);
// Make sure we don't hold on to any locks during the enumerateCB, so copy the registry info to a local variable
// and unlock the registryMutex before calling the callback.
m_registryMutex.lock();
auto assetIdToInfoCopy = m_registry->m_assetIdToInfo;
m_registryMutex.unlock();
for (auto& it : m_registry->m_assetIdToInfo)
for (auto& it : assetIdToInfoCopy)
{
enumerateCB(it.first, it.second);
}
@@ -508,6 +527,12 @@ namespace AzFramework
{
endCB();
}
if (hasAssetCatalogMutex)
{
// Relock the mutex if it was unlocked earlier
assetCatalogContext->m_contextMutex.lock();
}
}
//=========================================================================
@@ -161,6 +161,11 @@ namespace AzFramework
SurfacePointListFillCallback perPositionCallback,
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
//! Returns the number of samples for a given region and step size. The first and second
//! elements of the pair correspond to the X and Y sample counts respectively.
virtual AZStd::pair<size_t, size_t> GetNumSamplesFromRegion(const AZ::Aabb& inRegion,
const AZ::Vector2& stepSize) const = 0;
//! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the
//! coordinates in the region.
virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion,
@@ -14,6 +14,7 @@
#include <AzCore/Interface/Interface.h>
#include <AzCore/IO/Streamer/Streamer.h>
#include <AzCore/IO/Streamer/StreamerComponent.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Jobs/JobManager.h>
#include <AzCore/Jobs/JobContext.h>
#include <AzCore/Math/Uuid.h>
@@ -21,6 +22,7 @@
#include <AzCore/Memory/PoolAllocator.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzFramework/Asset/AssetCatalog.h>
@@ -931,6 +933,109 @@ namespace UnitTest
EXPECT_FALSE(m_assetCatalog->DoesAssetIdMatchWildcardPattern(m_firstAssetId, ""));
}
TEST_F(AssetCatalogAPITest, EnumerateAssetsListsCorrectAssets)
{
AZStd::vector<AssetId> foundAssets;
AZ::Data::AssetCatalogRequestBus::Broadcast(
&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr,
[&foundAssets](const AZ::Data::AssetId assetId, [[maybe_unused]] const AZ::Data::AssetInfo& assetInfo)
{
foundAssets.emplace_back(assetId);
},
nullptr);
ASSERT_EQ(foundAssets.size(), 2);
EXPECT_EQ(foundAssets[0], m_firstAssetId);
EXPECT_EQ(foundAssets[1], m_secondAssetId);
}
TEST_F(AssetCatalogAPITest, EnumerateAssetsDoesNotBlockMutex)
{
// This test simulates a previously-occurring deadlock bug caused by having the main thread call AssetCatalog::EnumerateAssets
// with a callback that calls the AssetManager, and a loading thread running underneath the AssetManager that calls the
// AssetCatalog.
// To reproduce this state, we will do the following:
// Main Thread Job Thread
// wait on mainToJobSync
// call EnumerateAssets
// unblock mainToJobSync
// wait on jobToMainSync call AssetCatalog::X
// unblock jobToMainSync
//
// These steps should ensure that we create a theoretical "lock inversion", if EnumerateAssets locked an AssetCatalog mutex.
// Even though we're using binary semaphores instead of mutexes, we're creating the same blocking situation.
// EnumerateAssets itself should no longer lock the AssetCatalog mutex, so this test should succeed since there won't be any
// actual lock inversion.
// Set up job manager with one thread that we can use to set up the concurrent mutex access.
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
AZ::JobManagerDesc desc;
AZ::JobManagerThreadDesc threadDesc;
desc.m_workerThreads.push_back(threadDesc);
auto jobManager = aznew AZ::JobManager(desc);
auto jobContext = aznew AZ::JobContext(*jobManager);
AZ::JobContext::SetGlobalContext(jobContext);
AZStd::binary_semaphore mainToJobSync;
AZStd::binary_semaphore jobToMainSync;
// Create a job whose sole purpose is to wait for EnumerateAssets to get called, call AssetCatalog, then tell EnumerateAssets
// to finish. If EnumerateAssets has a mutex held, this will deadlock.
auto job = AZ::CreateJobFunction(
[&mainToJobSync, &jobToMainSync]() mutable
{
// wait for the main thread to be inside the EnumerateAssets callback.
mainToJobSync.acquire();
// call AssetCatalog::X. This will deadlock if EnumerateAssets is holding an AssetCatalog mutex.
[[maybe_unused]] AZStd::string assetPath;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetPath, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, AZ::Data::AssetId());
// signal the main thread to continue
jobToMainSync.release();
},
true);
job->Start();
bool testCompletedSuccessfully = false;
// Call EnumerateAssets with a callback that also tries to lock the mutex.
AZ::Data::AssetCatalogRequestBus::Broadcast(
&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr,
[this, &mainToJobSync, &jobToMainSync, &testCompletedSuccessfully]
(const AZ::Data::AssetId assetId, [[maybe_unused]] const AZ::Data::AssetInfo& assetInfo)
{
// Only run this logic on the first assetId.
if (assetId == m_firstAssetId)
{
// Tell the job it can continue
mainToJobSync.release();
// Wait for the job to finish calling AssetCatalog::X. This will deadlock if EnumerateAssets is holding an
// AssetCatalog mutex.
if (jobToMainSync.try_acquire_for(AZStd::chrono::seconds(5)))
{
// Only mark the test as completed successfully if we ran this logic and didn't deadlock.
testCompletedSuccessfully = true;
}
}
},
nullptr);
EXPECT_TRUE(testCompletedSuccessfully);
// Clean up the job manager
AZ::JobContext::SetGlobalContext(nullptr);
delete jobContext;
delete jobManager;
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
}
class AssetType1
: public AssetData
{
@@ -92,6 +92,8 @@ namespace UnitTest
ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
MOCK_CONST_METHOD3(
ProcessSurfacePointsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
MOCK_CONST_METHOD2(
GetNumSamplesFromRegion, AZStd::pair<size_t, size_t>(const AZ::Aabb&, const AZ::Vector2&));
MOCK_CONST_METHOD4(
ProcessHeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
MOCK_CONST_METHOD4(
@@ -383,7 +383,7 @@ namespace AzNetworking
if (compErr != CompressorError::Ok)
{
AZLOG_ERROR("Decompress failed with error %d this will lead to data read errors!", compErr);
AZLOG_ERROR("Decompress failed with error %d this will lead to data read errors!", aznumeric_cast<int32_t>(compErr));
return false;
}
@@ -35,7 +35,7 @@ namespace AzNetworking
bool TcpConnectionSet::DeleteConnection(SocketFd socketFd)
{
AZLOG(TcpConnectionSet, "Deleting Tcp connection by socketId (%u)", socketFd);
AZLOG(TcpConnectionSet, "Deleting Tcp connection by socketId (%u)", aznumeric_cast<int32_t>(socketFd));
TcpConnection* connection = GetConnection(socketFd);
if (connection == nullptr)
{
@@ -446,7 +446,7 @@ namespace AzNetworking
if (compErr != CompressorError::Ok)
{
AZLOG_ERROR("Decompress failed with error %d this will lead to data read errors!", compErr);
AZLOG_ERROR("Decompress failed with error %d this will lead to data read errors!", aznumeric_cast<int32_t>(compErr));
return false;
}
@@ -15,8 +15,6 @@
#define AZ_TRAIT_DISABLE_FAILED_NATIVE_WINDOWS_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_DLL_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_MODULE_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_EDITOR_TESTS true
// Golden perline gradiant values for random seed 7878 for this platform
@@ -43,7 +43,6 @@ namespace AzToolsFramework
{
friend class AssetBrowserModel;
friend class AssetBrowserFilterModel;
friend class AssetBrowserEntry;
friend class RootAssetBrowserEntry;
friend class FolderAssetBrowserEntry;
friend class SourceAssetBrowserEntry;
@@ -230,7 +230,10 @@ namespace AzToolsFramework
{
QModelIndex curIndex = selectedIndexes[0];
m_expandToEntriesByDefault = true;
m_treeStateSaver->ApplySnapshot();
if (m_treeStateSaver)
{
m_treeStateSaver->ApplySnapshot();
}
setCurrentIndex(curIndex);
scrollTo(curIndex);
@@ -240,8 +243,12 @@ namespace AzToolsFramework
// Flag our default expansion state so that we expand down to source entries after filtering
m_expandToEntriesByDefault = hasFilter;
// Then ask our state saver to apply its current snapshot again, falling back on asking us if entries should be expanded or not
m_treeStateSaver->ApplySnapshot();
if (m_treeStateSaver)
{
m_treeStateSaver->ApplySnapshot();
}
// If we're filtering for a valid entry, select the first valid entry
if (hasFilter && selectFirstValidEntry)
@@ -290,6 +290,7 @@ namespace AzToolsFramework
{
displayString = RichTextHighlighter::HighlightText(displayString, m_assetBrowserFilerModel->GetStringFilter()->GetFilterString());
}
RichTextHighlighter::PaintHighlightedRichText(displayString, painter, optionV4, remainingRect);
}
}
@@ -29,12 +29,11 @@ namespace AzToolsFramework
return highlightedString;
}
void RichTextHighlighter::PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect)
void RichTextHighlighter::PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect, QPoint offset /* = QPoint()*/)
{
// Now we setup a Text Document so it can draw the rich text
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
// Now we setup a Text Document so it can draw the rich text
QTextDocument textDoc;
textDoc.setDefaultFont(option.font);
if (option.state & QStyle::State_Enabled)
@@ -46,10 +45,9 @@ namespace AzToolsFramework
textDoc.setDefaultStyleSheet("body {color: #7C7C7C}");
}
textDoc.setHtml("<body>" + highlightedString + "</body>");
painter->translate(availableRect.topLeft());
painter->translate(availableRect.topLeft() + offset);
textDoc.setTextWidth(availableRect.width());
textDoc.drawContents(painter, QRectF(0, 0, availableRect.width(), availableRect.height()));
painter->restore();
}
} // namespace AzToolsFramework
@@ -30,7 +30,8 @@ namespace AzToolsFramework
RichTextHighlighter() = delete;
static QString HighlightText(const QString& displayString, const QString& matchingSubstring);
static void PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect);
static void PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option,
QRect availableRect, QPoint offset = QPoint());
};
} // namespace AzToolsFramework
@@ -201,11 +201,8 @@ namespace AzToolsFramework
//! Fired after the EditorEntityContext fails to export the root level slice to the game stream
virtual void OnSaveStreamForGameFailure(AZStd::string_view /*failureString*/) {}
//! Fired when the user triggers a clone of ComponentEntity object(s), before operation begins
virtual void OnEntitiesAboutToBeCloned() {}
//! Fires when the user triggers a clone of ComponentEntity object(s)), after operation completes
virtual void OnEntitiesCloned() {}
//! Preserve entity order when re-parenting entities
virtual void SetForceAddEntitiesToBackFlag(bool /*forceAddToBack*/) {}
};
@@ -1157,7 +1157,7 @@ namespace AzToolsFramework
bool CloneInstantiatedEntities(const EntityIdSet& entitiesToClone, EntityIdSet& clonedEntities)
{
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesAboutToBeCloned);
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true);
ScopedUndoBatch undoBatch("Clone Selection");
// Track the mapping of source to cloned entity. This both helps make sure that an entity is not accidentally
@@ -1199,7 +1199,7 @@ namespace AzToolsFramework
// Also replace the selection with the entities that have been cloned.
Internal::UpdateUndoStackAndSelectClonedEntities(allEntityClonesContainer.m_entities, undoBatch);
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesCloned);
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false);
for (const AZ::Entity* entity : allEntityClonesContainer.m_entities)
{
@@ -69,7 +69,7 @@ namespace AzToolsFramework
{
return nullptr;
}
return entity->FindComponent<ComponentType>();
return entity->template FindComponent<ComponentType>();
}
};
@@ -643,14 +643,9 @@ namespace AzToolsFramework
}
}
void EditorEntityModel::OnEntitiesAboutToBeCloned()
void EditorEntityModel::SetForceAddEntitiesToBackFlag(bool forceAddToBack)
{
m_forceAddToBack = true;
}
void EditorEntityModel::OnEntitiesCloned()
{
m_forceAddToBack = false;
m_forceAddToBack = forceAddToBack;
}
void EditorEntityModel::ChildEntityOrderArrayUpdated()
@@ -94,9 +94,7 @@ namespace AzToolsFramework
void OnEntityStreamLoadBegin() override;
void OnEntityStreamLoadSuccess() override;
void OnEntityStreamLoadFailed() override;
void OnEntitiesAboutToBeCloned() override;
void OnEntitiesCloned() override;
void SetForceAddEntitiesToBackFlag(bool forceAddToBack) override;
////////////////////////////////////////////////
// AzFramework::EntityContextEventBus::Handler
@@ -11,6 +11,7 @@
#include <AzCore/JSON/writer.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Utils/TypeHash.h>
#include <AzCore/std/sort.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
@@ -83,6 +84,20 @@ namespace AzToolsFramework
return AZ::Failure(findCommonRootOutcome.TakeError());
}
// order entities by their respective position within Entity Outliner
EditorEntitySortRequestBus::Event(
commonRootEntityId,
[&topLevelEntities](EditorEntitySortRequestBus::Events* sortRequests)
{
AZStd::sort(
topLevelEntities.begin(), topLevelEntities.end(),
[&sortRequests](AZ::Entity* entity1, AZ::Entity* entity2)
{
return sortRequests->GetChildEntityIndex(entity1->GetId()) <
sortRequests->GetChildEntityIndex(entity2->GetId());
});
});
AZ::EntityId containerEntityId;
InstanceOptionalReference instanceToCreate;
@@ -153,8 +168,6 @@ namespace AzToolsFramework
}
// Create the Prefab
AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInMemory requires an absolute file path.");
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(filePath),
commonRootEntityOwningInstance);
@@ -172,6 +185,7 @@ namespace AzToolsFramework
// Parent the non-container top level entities to the container entity.
// Parenting the top level container entities will be done during the creation of links.
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true);
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
if (!IsInstanceContainerEntity(topLevelEntity->GetId()))
@@ -179,6 +193,7 @@ namespace AzToolsFramework
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
}
}
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false);
// Update the template of the instance since the entities are modified since the template creation.
Prefab::PrefabDom serializedInstance;
@@ -279,6 +294,8 @@ namespace AzToolsFramework
CreatePrefabResult PrefabPublicHandler::CreatePrefabInDisk(const EntityIdList& entityIds, AZ::IO::PathView filePath)
{
AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInDisk requires an absolute file path.");
auto result = CreatePrefabInMemory(entityIds, filePath);
if (result.IsSuccess())
{
@@ -3460,7 +3460,7 @@ namespace AzToolsFramework
static const AZ::u32 kPixelIndentationPerLevel = GetSliceHierarchyMenuIdentationPerLevel();
// Any asset that acts as a valid target for all selected slice-instance-owned entities can be shown.
QMenu* quickPushMenu = quickPushMenu = new QMenu(parent);
QMenu* quickPushMenu = new QMenu(parent);
bool setupMenu = false;
if (pushableChangesAvailable)
@@ -139,7 +139,7 @@ namespace AZStd
};
template <>
struct AZStd::equal_to<AzToolsFramework::Thumbnailer::SharedThumbnailKey>
struct equal_to<AzToolsFramework::Thumbnailer::SharedThumbnailKey>
{
AZ_FORCE_INLINE bool operator()(const AzToolsFramework::Thumbnailer::SharedThumbnailKey& left, const AzToolsFramework::Thumbnailer::SharedThumbnailKey& right) const
{
@@ -2368,6 +2368,8 @@ namespace AzToolsFramework
AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect);
painter->restore();
EntityOutlinerListModel::s_paintingName = false;
}
-1
View File
@@ -18,7 +18,6 @@ ly_add_target(
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
${common_dir}/gridmate_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PUBLIC
.
@@ -1702,7 +1702,7 @@ CarrierThread::UpdateReceive()
if (compErr != CompressorError::Ok)
{
AZ_Error("GridMate", compErr == CompressorError::Ok, "Decompress failed with error %d this will lead to data read errors!", compErr);
AZ_Error("GridMate", compErr == CompressorError::Ok, "Decompress failed with error %d this will lead to data read errors!", aznumeric_cast<int32_t>(compErr));
conn->m_isBadPackets = true;
break; /// stop processing this data
}
@@ -2136,7 +2136,7 @@ bool CarrierThread::SendDatagram(ThreadConnection* connection)
{
if (compErr != CompressorError::Ok)
{
AZ_Error("GridMate", compErr == CompressorError::Ok, "Failed to compress chunk with error=%d.\n", static_cast<int>(compErr));
AZ_Error("GridMate", compErr == CompressorError::Ok, "Failed to compress chunk with error=%d.\n", aznumeric_cast<int32_t>(compErr));
}
// we can use writeBuffer directly because we already added the compression hint to indicate that this data is uncompressed
@@ -1455,7 +1455,9 @@ namespace GridMate
ERR_load_SSL_strings();
SSL_load_error_strings();
AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations", "-Wdeprecated-declarations")
m_sslContext = SSL_CTX_new(DTLSv1_2_method());
AZ_POP_DISABLE_WARNING
if (m_sslContext == nullptr)
{
return EC_SECURE_CREATE;
@@ -47,7 +47,10 @@ namespace GridMate
{
if (s_initializeOpenSSLCount.fetch_sub(1) == 1)
{
AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations", "-Wdeprecated-declarations")
ERR_remove_state(0);
AZ_POP_DISABLE_WARNING
ERR_free_strings();
EVP_cleanup();
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
@@ -85,7 +88,9 @@ namespace GridMate
{
return Driver::EC_SECURE_CREATE;
}
AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations", "-Wdeprecated-declarations")
m_ctx = SSL_CTX_new(TLSv1_2_method());
AZ_POP_DISABLE_WARNING
if (m_ctx == nullptr)
{
return Driver::EC_SECURE_CREATE;
+15 -1
View File
@@ -10,14 +10,17 @@
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Component/ComponentApplicationLifecycle.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Debug/BudgetTracker.h>
#include <AzCore/Debug/Trace.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/IO/RemoteStorageDrive.h>
#include <AzFramework/Windowing/NativeWindow.h>
@@ -571,6 +574,17 @@ namespace O3DELauncher
}
#if !defined(AZ_MONOLITHIC_BUILD)
#if !defined(_RELEASE)
// until CrySystem can be removed (or made to be managed by the component application),
// we need to manually clear the BudgetTracker before CrySystem is unloaded so the Budget
// pointer(s) it has references to are cleared properly
if (auto budgetTracker = AZ::Interface<AZ::Debug::BudgetTracker>::Get(); budgetTracker)
{
budgetTracker->Reset();
}
#endif // !defined(_RELEASE)
delete systemInitParams.pSystem;
crySystemLibrary.reset(nullptr);
#endif // !defined(AZ_MONOLITHIC_BUILD)
+1 -1
View File
@@ -164,7 +164,7 @@ AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
char s[1024];
//! Use strftime to build a customized time string.
strftime(s, 128, "Logged at %#c\n", today);
strftime(s, 128, "Logged at %c\n", today);
azstrcat(str, length, s);
sprintf_s(s, "FileVersion: %s\n", sFileVersion);
azstrcat(str, length, s);
-42
View File
@@ -115,43 +115,6 @@ extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExce
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
#include <execinfo.h>
#include <signal.h>
void CryEngineSignalHandler(int signal)
{
char resolvedPath[_MAX_PATH];
// it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath("@log@/crash.log", resolvedPath, _MAX_PATH))
{
fprintf(stderr, "Crash Signal Handler - logged to %s\n", resolvedPath);
FILE* file = fopen(resolvedPath, "a");
if (file)
{
char sTime[128];
time_t ltime;
time(&ltime);
struct tm* today = localtime(&ltime);
strftime(sTime, 40, "<%Y-%m-%d %H:%M:%S> ", today);
fprintf(file, "%s: Error: signal %s:\n", sTime, strsignal(signal));
fflush(file);
void* array[100];
int s = backtrace(array, 100);
backtrace_symbols_fd(array, s, fileno(file));
fclose(file);
CryLogAlways("Successfully recorded crash file: '%s'", resolvedPath);
abort();
}
}
CryLogAlways("Could not record crash file...");
abort();
}
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
//////////////////////////////////////////////////////////////////////////
#define DEFAULT_LOG_FILENAME "@log@/Log.txt"
@@ -697,11 +660,6 @@ public:
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::Init(const SSystemInitParams& startupParams)
{
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
signal(SIGSEGV, CryEngineSignalHandler);
signal(SIGTRAP, CryEngineSignalHandler);
signal(SIGILL, CryEngineSignalHandler);
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
-1
View File
@@ -11,7 +11,6 @@
#include <stdlib.h>
#define XML_STATIC // Alternative to defining this here would be setting it project-wide
#include <expat.h>
#include "xml.h"
#include <algorithm>

Some files were not shown because too many files have changed in this diff Show More