Merge remote-tracking branch 'upstream/development' into michabr/lyshine_crycommon
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Ui
|
||||
|
||||
class EditorPreferencesTreeWidgetItem;
|
||||
|
||||
void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event);
|
||||
bool WidgetConsumesKeyPressEvent(QKeyEvent* event);
|
||||
|
||||
class EditorPreferencesDialog
|
||||
: public QDialog
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
-1
@@ -43,7 +43,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
friend class AssetBrowserModel;
|
||||
friend class AssetBrowserFilterModel;
|
||||
friend class AssetBrowserEntry;
|
||||
friend class RootAssetBrowserEntry;
|
||||
friend class FolderAssetBrowserEntry;
|
||||
friend class SourceAssetBrowserEntry;
|
||||
|
||||
+9
-2
@@ -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
|
||||
{
|
||||
|
||||
+2
@@ -2368,6 +2368,8 @@ namespace AzToolsFramework
|
||||
|
||||
AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect);
|
||||
|
||||
painter->restore();
|
||||
|
||||
EntityOutlinerListModel::s_paintingName = false;
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -5,4 +5,3 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(<ime);
|
||||
struct tm* today = localtime(<ime);
|
||||
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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user