Merge remote-tracking branch 'upstream/development' into nvsickle/GenericDomDocument

This commit is contained in:
Nicholas Van Sickle
2022-01-04 15:41:17 -08:00
464 changed files with 23577 additions and 10203 deletions
-7
View File
@@ -30,8 +30,6 @@ CAboutDialog::CAboutDialog(QString versionText, QString richTextCopyrightNotice,
m_ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
connect(m_ui->m_transparentAgreement, &QLabel::linkActivated, this, &CAboutDialog::OnCustomerAgreement);
m_ui->m_transparentTrademarks->setText(versionText);
m_ui->m_transparentAllRightReserved->setObjectName("copyrightNotice");
@@ -84,9 +82,4 @@ void CAboutDialog::mouseReleaseEvent(QMouseEvent* event)
QDialog::mouseReleaseEvent(event);
}
void CAboutDialog::OnCustomerAgreement()
{
QDesktopServices::openUrl(QUrl(QStringLiteral("https://www.o3debinaries.org/license")));
}
#include <moc_AboutDialog.cpp>
-2
View File
@@ -30,8 +30,6 @@ public:
private:
void OnCustomerAgreement();
void mouseReleaseEvent(QMouseEvent* event) override;
void paintEvent(QPaintEvent* event) override;
+6 -8
View File
@@ -181,14 +181,17 @@
</spacer>
</item>
<item>
<widget class="ClickableLabel" name="m_transparentAgreement">
<widget class="QLabel" name="m_transparentAgreement">
<property name="text">
<string>Terms of Use</string>
<string>&lt;a href=&quot;https://www.o3debinaries.org/license&quot;&gt;Terms of Use&lt;/a&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="showDecoration" stdset="0">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
@@ -274,11 +277,6 @@
<extends>QWidget</extends>
<header>qsvgwidget.h</header>
</customwidget>
<customwidget>
<class>ClickableLabel</class>
<extends>QLabel</extends>
<header>QtUI/ClickableLabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
@@ -1,30 +0,0 @@
/*
* 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 "EditorDefs.h"
#include "AnimationBipedBoneNames.h"
namespace EditorAnimationBones::Biped
{
const char* Pelvis = "Bip01 Pelvis";
const char* Head = "Bip01 Head";
const char* Weapon = "weapon_bone";
const char* LeftEye = "eye_bone_left";
const char* RightEye = "eye_bone_right";
const char* Spine[5] = { "Bip01 Spine", "Bip01 Spine1", "Bip01 Spine2", "Bip01 Spine3", "Bip01 Spine4" };
const char* Neck[2] = { "Bip01 Neck", "Bip01 Neck1" };
const char* LeftHeel = "Bip01 L Heel";
const char* LeftToe[2] = { "Bip01 L Toe0", "Bip01 L Toe1" };
const char* RightHeel = "Bip01 R Heel";
const char* RightToe[2] = { "Bip01 R Toe0", "Bip01 R Toe1" };
} // namespace EditorAnimationBones::Biped
@@ -1,34 +0,0 @@
/*
* 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
*
*/
#ifndef CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
#define CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
#pragma once
namespace EditorAnimationBones
{
namespace Biped
{
extern const char* Pelvis;
extern const char* Head;
extern const char* Weapon;
extern const char* Spine[5];
extern const char* Neck[2];
extern const char* LeftEye;
extern const char* RightEye;
extern const char* LeftHeel;
extern const char* RightHeel;
extern const char* LeftToe[2];
extern const char* RightToe[2];
}
}
#endif // CRYINCLUDE_EDITOR_ANIMATION_ANIMATIONBIPEDBONENAMES_H
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:58ef978b31b31df9aaf715a0e9b006fde414a17a3ff15a3bf680eaad7418867a
size 364
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:98a681ec3d89ee57c5d1057fe984dcf8ad45721f47ae4df57fa358fbee85e616
size 385
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:24a2b2c9242a841c20e7815dab0d80a575844055328aea413d28b7283b65a92e
size 386
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ce23a276fec849b8f832fab96d3b738793335c27d37ae3813158387f3415b508
size 377
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c03befab41765200f4f28dbf1e0b2a702d2244bfa79b0d463f5d58d0a26095fc
size 386
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:418c3f0f27854b3795841359014d87686a7bf94daf2568d9cfd3ffac22675f69
size 386
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3a831f34ac53c9b1f20037290e8a2b62a3cfb8a4f86467591f44fd2a0e3c15b
size 379
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4267102ca7a889c34eff905480a68878d4d56e15bc723a5b0575cd472e259f5d
size 389
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a0df013dd102b87348fba18b4da5443591309e9c40166d27ae928636924154ea
size 388
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e713076ab5abbbb2cf28da431a339e9905acc790e35295f025aa2e79e1c04141
size 376
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9e5af9d62ceafc3b8a1dfc36772350cd623fcc86c68711b299e143ff133f79b6
size 387
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:17c5fb3d7b87ea87a98934954c721573c641bc44005a34f1e16589d7f39b71e8
size 409
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6f5c78d9f764b62fb7dcf400c91c1edea9d7f88a426ba513fbf70825c6bcd2ac
size 383
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:376b549602afffca407525b77c1a9821bf6a0e279792ae2e52fe0a4f7c3c5bd4
size 364
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e7dc48f8d324b7563b168f27ebde1e00ee2bd11ba462f114a05b297913e285c5
size 374
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:66b73afbd6dba1caaedfaae161b277b460b5198f7fc00bec414530116c567276
size 375
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ae6e6714acf495246f4e59f6e5640f3a4417ea50100d37a116950d2b859aed0c
size 417
+9 -3
View File
@@ -104,6 +104,11 @@ namespace
}
}
// Currently (December 13, 2021), this function is only used by slice editor code.
// When the slice editor is not enabled, there are no references to the
// HideActionWhileEntitiesDeselected function, causing a compiler warning and
// subsequently a build error.
#ifdef ENABLE_SLICE_EDITOR
void HideActionWhileEntitiesDeselected(QAction* action, EEditorNotifyEvent editorNotifyEvent)
{
if (action == nullptr)
@@ -127,6 +132,7 @@ namespace
break;
}
}
#endif
void DisableActionWhileInSimMode(QAction* action, EEditorNotifyEvent editorNotifyEvent)
{
@@ -374,7 +380,6 @@ QMenu* LevelEditorMenuHandler::CreateFileMenu()
{
DisableActionWhileLevelChanges(fileOpenSlice, e);
}));
#endif
// Save Selected Slice
auto saveSelectedSlice = fileMenu.AddAction(ID_FILE_SAVE_SELECTED_SLICE);
@@ -391,7 +396,7 @@ QMenu* LevelEditorMenuHandler::CreateFileMenu()
{
HideActionWhileEntitiesDeselected(saveSliceToRoot, e);
}));
#endif
// Open Recent
m_mostRecentLevelsMenu = fileMenu.AddMenu(tr("Open Recent"));
connect(m_mostRecentLevelsMenu, &QMenu::aboutToShow, this, &LevelEditorMenuHandler::UpdateMRUFiles);
@@ -439,9 +444,10 @@ QMenu* LevelEditorMenuHandler::CreateFileMenu()
// Show Log File
fileMenu.AddAction(ID_FILE_EDITLOGFILE);
#ifdef ENABLE_SLICE_EDITOR
fileMenu.AddSeparator();
fileMenu.AddAction(ID_FILE_RESAVESLICES);
#endif
fileMenu.AddSeparator();
+3 -1
View File
@@ -380,13 +380,13 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_IMPORT_ASSET, OnOpenAssetImporter)
ON_COMMAND(ID_EDIT_LEVELDATA, OnEditLevelData)
ON_COMMAND(ID_FILE_EDITLOGFILE, OnFileEditLogFile)
ON_COMMAND(ID_FILE_RESAVESLICES, OnFileResaveSlices)
ON_COMMAND(ID_FILE_EDITEDITORINI, OnFileEditEditorini)
ON_COMMAND(ID_PREFERENCES, OnPreferences)
ON_COMMAND(ID_REDO, OnRedo)
ON_COMMAND(ID_TOOLBAR_WIDGET_REDO, OnRedo)
ON_COMMAND(ID_FILE_OPEN_LEVEL, OnOpenLevel)
#ifdef ENABLE_SLICE_EDITOR
ON_COMMAND(ID_FILE_RESAVESLICES, OnFileResaveSlices)
ON_COMMAND(ID_FILE_NEW_SLICE, OnCreateSlice)
ON_COMMAND(ID_FILE_OPEN_SLICE, OnOpenSlice)
#endif
@@ -2629,6 +2629,7 @@ void CCryEditApp::OnFileEditLogFile()
CFileUtil::EditTextFile(CLogFile::GetLogFileName(), 0, IFileUtil::FILE_TYPE_SCRIPT);
}
#ifdef ENABLE_SLICE_EDITOR
void CCryEditApp::OnFileResaveSlices()
{
AZStd::vector<AZ::Data::AssetInfo> sliceAssetInfos;
@@ -2759,6 +2760,7 @@ void CCryEditApp::OnFileResaveSlices()
}
}
#endif
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnFileEditEditorini()
+2 -2
View File
@@ -319,8 +319,8 @@ public:
keys.push_back(QPair<QString, QString>("Edit Menu.Duplicate", "Ctrl+D"));
keys.push_back(QPair<QString, QString>("Edit Menu.Undo", "Ctrl+Z"));
keys.push_back(QPair<QString, QString>("Edit Menu.Redo", "Ctrl+Shift+Z"));
keys.push_back(QPair<QString, QString>("Edit Menu.Group", "Ctrl+G"));
keys.push_back(QPair<QString, QString>("Edit Menu.Ungroup", "Ctrl+Shift+G"));
keys.push_back(QPair<QString, QString>("Edit Menu.Group", "Ctrl+Alt+O"));
keys.push_back(QPair<QString, QString>("Edit Menu.Ungroup", "Ctrl+Alt+P"));
keys.push_back(QPair<QString, QString>("Edit Menu.Rename", "Ctrl+R"));
keys.push_back(QPair<QString, QString>("Edit Menu.Reset", ""));
keys.push_back(QPair<QString, QString>("Edit Menu.Edit Hotkeys", ""));
+1 -1
View File
@@ -1445,7 +1445,7 @@ ISourceControl* CEditorImpl::GetSourceControl()
{
IClassDesc* pClass = classes[i];
ISourceControl* pSCM = nullptr;
HRESULT hRes = pClass->QueryInterface(__uuidof(ISourceControl), (void**)&pSCM);
HRESULT hRes = pClass->QueryInterface(__az_uuidof(ISourceControl), (void**)&pSCM);
if (!FAILED(hRes) && pSCM)
{
m_pSourceControl = pSCM;
+2 -5
View File
@@ -31,10 +31,7 @@ struct IUnknown
};
#endif
#ifdef __uuidof
#undef __uuidof
#endif
#define __uuidof(T) T::uuid()
#define __az_uuidof(T) T::uuid()
#if defined(AZ_PLATFORM_LINUX) || defined(AZ_PLATFORM_MAC)
@@ -107,7 +104,7 @@ struct IClassDesc
template<class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
return QueryInterface(__az_uuidof(Q), (void**)pp);
}
//////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -60,7 +60,7 @@ struct IViewPaneClass
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE QueryInterface(const IID& riid, void** ppvObj)
{
if (riid == __uuidof(IViewPaneClass))
if (riid == __az_uuidof(IViewPaneClass))
{
*ppvObj = this;
return S_OK;
@@ -1,58 +0,0 @@
/*
* 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 "EditorDefs.h"
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <QtUI/ClickableLabel.h>
#include <QApplication>
using namespace AZ;
using namespace ::testing;
namespace UnitTest
{
class TestingClickableLabel
: public ScopedAllocatorSetupFixture
{
public:
ClickableLabel m_clickableLabel;
};
TEST_F(TestingClickableLabel, CursorDoesNotUpdateWhileDisabled)
{
m_clickableLabel.setEnabled(false);
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
QEnterEvent enterEvent{ QPointF(), QPointF(), QPointF() };
QApplication::sendEvent(&m_clickableLabel, &enterEvent);
const Qt::CursorShape cursorShape = QApplication::overrideCursor()->shape();
EXPECT_THAT(cursorShape, Ne(Qt::PointingHandCursor));
EXPECT_THAT(cursorShape, Eq(Qt::BlankCursor));
}
TEST_F(TestingClickableLabel, DoesNotRespondToDblClickWhileDisabled)
{
m_clickableLabel.setEnabled(false);
bool linkActivated = false;
QObject::connect(&m_clickableLabel, &QLabel::linkActivated, [&linkActivated]()
{
linkActivated = true;
});
QMouseEvent mouseEvent {
QEvent::MouseButtonDblClick, QPointF(),
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier };
QApplication::sendEvent(&m_clickableLabel, &mouseEvent);
EXPECT_THAT(linkActivated, Eq(false));
}
} // namespace UnitTest
+3 -1
View File
@@ -643,11 +643,11 @@ void MainWindow::InitActions()
.SetStatusTip(tr("Create a new slice"));
am->AddAction(ID_FILE_OPEN_SLICE, tr("Open Slice..."))
.SetStatusTip(tr("Open an existing slice"));
#endif
am->AddAction(ID_FILE_SAVE_SELECTED_SLICE, tr("Save selected slice")).SetShortcut(tr("Alt+S"))
.SetStatusTip(tr("Save the selected slice to the first level root"));
am->AddAction(ID_FILE_SAVE_SLICE_TO_ROOT, tr("Save Slice to root")).SetShortcut(tr("Ctrl+Alt+S"))
.SetStatusTip(tr("Save the selected slice to the top level root"));
#endif
am->AddAction(ID_FILE_SAVE_LEVEL, tr("&Save"))
.SetShortcut(tr("Ctrl+S"))
.SetReserved()
@@ -677,7 +677,9 @@ void MainWindow::InitActions()
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSelected);
am->AddAction(ID_FILE_EXPORTOCCLUSIONMESH, tr("Export Occlusion Mesh"));
am->AddAction(ID_FILE_EDITLOGFILE, tr("Show Log File"));
#ifdef ENABLE_SLICE_EDITOR
am->AddAction(ID_FILE_RESAVESLICES, tr("Resave All Slices"));
#endif
am->AddAction(ID_FILE_PROJECT_MANAGER_SETTINGS, tr("Edit Project Settings..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_NEW, tr("New Project..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_OPEN, tr("Open Project..."));
+1 -1
View File
@@ -155,7 +155,7 @@ IViewPaneClass* CClassFactory::FindViewPaneClassByTitle(const char* pPaneTitle)
{
IViewPaneClass* viewPane = nullptr;
IClassDesc* desc = m_classes[i];
if (SUCCEEDED(desc->QueryInterface(__uuidof(IViewPaneClass), (void**)&viewPane)))
if (SUCCEEDED(desc->QueryInterface(__az_uuidof(IViewPaneClass), (void**)&viewPane)))
{
if (QString::compare(viewPane->GetPaneTitle(), pPaneTitle) == 0)
{
@@ -49,7 +49,7 @@ public:
// from IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(const IID& riid, void** ppvObj)
{
if (riid == __uuidof(ISourceControl) /* && m_pIntegrator*/)
if (riid == __az_uuidof(ISourceControl) /* && m_pIntegrator*/)
{
*ppvObj = this;
return S_OK;
+1 -1
View File
@@ -50,7 +50,7 @@ CStdPreferencesClassDesc::CStdPreferencesClassDesc()
HRESULT CStdPreferencesClassDesc::QueryInterface(const IID& riid, void** ppvObj)
{
if (riid == __uuidof(IPreferencesPageCreator))
if (riid == __az_uuidof(IPreferencesPageCreator))
{
*ppvObj = (IPreferencesPageCreator*)this;
return S_OK;
-101
View File
@@ -1,101 +0,0 @@
/*
* 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 "EditorDefs.h"
#include "ClickableLabel.h"
ClickableLabel::ClickableLabel(const QString& text, QWidget* parent)
: QLabel(parent)
, m_text(text)
, m_showDecoration(false)
{
setTextFormat(Qt::RichText);
setTextInteractionFlags(Qt::TextBrowserInteraction);
}
ClickableLabel::ClickableLabel(QWidget* parent)
: QLabel(parent)
, m_showDecoration(false)
{
setTextFormat(Qt::RichText);
setTextInteractionFlags(Qt::TextBrowserInteraction);
}
void ClickableLabel::showEvent([[maybe_unused]] QShowEvent* event)
{
updateFormatting(false);
}
void ClickableLabel::enterEvent(QEvent* ev)
{
if (!isEnabled())
{
return;
}
updateFormatting(true);
QApplication::setOverrideCursor(QCursor(Qt::PointingHandCursor));
QLabel::enterEvent(ev);
}
void ClickableLabel::leaveEvent(QEvent* ev)
{
if (!isEnabled())
{
return;
}
updateFormatting(false);
QApplication::restoreOverrideCursor();
QLabel::leaveEvent(ev);
}
void ClickableLabel::setText(const QString& text)
{
m_text = text;
QLabel::setText(text);
updateFormatting(false);
}
void ClickableLabel::setShowDecoration(bool b)
{
m_showDecoration = b;
updateFormatting(false);
}
void ClickableLabel::updateFormatting(bool mouseOver)
{
//FIXME: this should be done differently. Using a style sheet would be easiest.
QColor c = palette().color(QPalette::WindowText);
if (mouseOver || m_showDecoration)
{
QLabel::setText(QString(R"(<a href="dummy" style="color: %1";>%2</a>)").arg(c.name(), m_text));
}
else
{
QLabel::setText(m_text);
}
}
bool ClickableLabel::event(QEvent* e)
{
if (isEnabled())
{
if (e->type() == QEvent::MouseButtonDblClick)
{
emit linkActivated(QString());
return true; //ignore
}
}
return QLabel::event(e);
}
#include <QtUI/moc_ClickableLabel.cpp>
-39
View File
@@ -1,39 +0,0 @@
/*
* 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
#ifndef CRYINCLUDE_EDITORCOMMON_CLICKABLELABEL_H
#define CRYINCLUDE_EDITORCOMMON_CLICKABLELABEL_H
#if !defined(Q_MOC_RUN)
#include <QLabel>
#endif
class SANDBOX_API ClickableLabel
: public QLabel
{
Q_OBJECT
public:
explicit ClickableLabel(const QString& text, QWidget* parent = nullptr);
explicit ClickableLabel(QWidget* parent = nullptr);
bool event(QEvent* e) override;
void setText(const QString& text);
void setShowDecoration(bool b);
protected:
void showEvent(QShowEvent* event) override;
void enterEvent(QEvent* ev) override;
void leaveEvent(QEvent* ev) override;
private:
void updateFormatting(bool mouseOver);
QString m_text;
bool m_showDecoration;
};
#endif
+1 -1
View File
@@ -251,7 +251,7 @@ bool CFileUtil::ExtractDccFilenameFromAssetDatabase(const QString& assetFilename
for (size_t i = 0; i < assetDatabasePlugins.size(); ++i)
{
if (assetDatabasePlugins[i]->QueryInterface(__uuidof(IAssetItemDatabase), (void**)&pCurrentDatabaseInterface) == S_OK)
if (assetDatabasePlugins[i]->QueryInterface(__az_uuidof(IAssetItemDatabase), (void**)&pCurrentDatabaseInterface) == S_OK)
{
if (!pCurrentDatabaseInterface)
{
-4
View File
@@ -297,8 +297,6 @@ set(FILES
Util/AffineParts.cpp
Objects/BaseObject.cpp
Objects/BaseObject.h
Animation/AnimationBipedBoneNames.cpp
Animation/AnimationBipedBoneNames.h
AnimationContext.cpp
AnimationContext.h
AzAssetBrowser/AzAssetBrowserRequestHandler.cpp
@@ -526,8 +524,6 @@ set(FILES
PythonEditorFuncs.h
QtUI/QCollapsibleGroupBox.h
QtUI/QCollapsibleGroupBox.cpp
QtUI/ClickableLabel.h
QtUI/ClickableLabel.cpp
QtUI/PixmapLabelPreview.h
QtUI/PixmapLabelPreview.cpp
QtUI/WaitCursor.h
-1
View File
@@ -8,7 +8,6 @@
set(FILES
Lib/Tests/IEditorMock.h
Lib/Tests/test_ClickableLabel.cpp
Lib/Tests/test_CryEditPythonBindings.cpp
Lib/Tests/test_CryEditDocPythonBindings.cpp
Lib/Tests/test_EditorPythonBindings.cpp
@@ -484,6 +484,7 @@ namespace AZ::IO
// as_posix
//! Replicates the behavior of the Python pathlib as_posix method
//! by replacing the Windows Path Separator with the Posix Path Seperator
constexpr string_type AsPosix() const;
AZStd::string StringAsPosix() const;
constexpr AZStd::fixed_string<MaxPathLength> FixedMaxPathStringAsPosix() const noexcept;
@@ -1043,6 +1043,13 @@ namespace AZ::IO
// as_posix
// Returns a copy of the path with the path separators converted to PosixPathSeparator
template <typename StringType>
constexpr auto BasicPath<StringType>::AsPosix() const -> string_type
{
string_type resultPath(m_path.begin(), m_path.end());
AZStd::replace(resultPath.begin(), resultPath.end(), WindowsPathSeparator, PosixPathSeparator);
return resultPath;
}
template <typename StringType>
AZStd::string BasicPath<StringType>::StringAsPosix() const
{
AZStd::string resultPath(m_path.begin(), m_path.end());
@@ -7,6 +7,8 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/functional.h>
@@ -35,10 +37,8 @@ namespace AZ::IO
size_t Save(const void* classPtr, IO::GenericStream& stream, bool) override
{
/// Save paths out using the PosixPathSeparator
PathType path(reinterpret_cast<const PathType*>(classPtr)->Native(), AZ::IO::PosixPathSeparator);
path.MakePreferred();
return static_cast<size_t>(stream.Write(path.Native().size(), path.c_str()));
auto posixPathString{ reinterpret_cast<const PathType*>(classPtr)->AsPosix() };
return static_cast<size_t>(stream.Write(posixPathString.size(), posixPathString.c_str()));
}
bool Load(void* classPtr, IO::GenericStream& stream, unsigned int, bool) override
@@ -73,5 +73,11 @@ namespace AZ::IO
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
;
}
else if (auto jsonContext = azrtti_cast<JsonRegistrationContext*>(context))
{
jsonContext->Serializer<JsonPathSerializer>()
->HandlesType<Path>()
->HandlesType<FixedMaxPath>();
}
}
}
@@ -109,6 +109,7 @@ namespace AZ
*/
static EnvironmentVariable<T*> s_instance;
static AZStd::shared_mutex s_mutex;
static bool s_instanceAssigned;
};
template <typename T>
@@ -117,6 +118,9 @@ namespace AZ
template <typename T>
AZStd::shared_mutex Interface<T>::s_mutex;
template <typename T>
bool Interface<T>::s_instanceAssigned;
template <typename T>
void Interface<T>::Register(T* type)
{
@@ -135,18 +139,19 @@ namespace AZ
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
s_instance = Environment::CreateVariable<T*>(GetVariableName());
s_instance.Get() = type;
s_instanceAssigned = true;
}
template <typename T>
void Interface<T>::Unregister(T* type)
{
if (!s_instance || !s_instance.Get())
if (!s_instanceAssigned)
{
AZ_Assert(false, "Interface '%s' not registered on this module!", AzTypeInfo<T>::Name());
return;
}
if (s_instance.Get() != type)
if (s_instance && s_instance.Get() != type)
{
AZ_Assert(false, "Interface '%s' is not the same instance that was registered! [Expected '%p', Found '%p']", AzTypeInfo<T>::Name(), type, s_instance.Get());
return;
@@ -156,6 +161,7 @@ namespace AZ
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
*s_instance = nullptr;
s_instance.Reset();
s_instanceAssigned = false;
}
template <typename T>
@@ -165,9 +171,9 @@ namespace AZ
// This is the fast path which won't block.
{
AZStd::shared_lock<AZStd::shared_mutex> lock(s_mutex);
if (s_instance)
if (s_instanceAssigned)
{
return s_instance.Get();
return s_instance ? s_instance.Get() : nullptr;
}
}
@@ -175,6 +181,7 @@ namespace AZ
// take the full lock and request it.
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
s_instance = Environment::FindVariable<T*>(GetVariableName());
s_instanceAssigned = true;
return s_instance ? s_instance.Get() : nullptr;
}
File diff suppressed because it is too large Load Diff
@@ -19,12 +19,14 @@ namespace AZ
AZ_MATH_INLINE Plane Plane::CreateFromNormalAndPoint(const Vector3& normal, const Vector3& point)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
return Plane(Simd::Vec4::ConstructPlane(normal.GetSimdValue(), point.GetSimdValue()));
}
AZ_MATH_INLINE Plane Plane::CreateFromNormalAndDistance(const Vector3& normal, float dist)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
Plane result;
result.Set(normal, dist);
return result;
@@ -33,6 +35,7 @@ namespace AZ
AZ_MATH_INLINE Plane Plane::CreateFromCoefficients(const float a, const float b, const float c, const float d)
{
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
Plane result;
result.Set(a, b, c, d);
return result;
@@ -65,18 +68,21 @@ namespace AZ
AZ_MATH_INLINE void Plane::Set(const Vector3& normal, float d)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
m_plane.Set(normal, d);
}
AZ_MATH_INLINE void Plane::Set(float a, float b, float c, float d)
{
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
m_plane.Set(a, b, c, d);
}
AZ_MATH_INLINE void Plane::SetNormal(const Vector3& normal)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
m_plane.SetX(normal.GetX());
m_plane.SetY(normal.GetY());
m_plane.SetZ(normal.GetZ());
+12 -4
View File
@@ -54,11 +54,11 @@ namespace AZ
//! Sets components using a Vector3 for the imaginary part and a float for the real part.
static Quaternion CreateFromVector3AndValue(const Vector3& v, float w);
//! Sets the quaternion to be a rotation around a specified axis.
//! Sets the quaternion to be a rotation around a specified axis in radians.
//! @{
static Quaternion CreateRotationX(float angle);
static Quaternion CreateRotationY(float angle);
static Quaternion CreateRotationZ(float angle);
static Quaternion CreateRotationX(float angleInRadians);
static Quaternion CreateRotationY(float angleInRadians);
static Quaternion CreateRotationZ(float angleInRadians);
//! @}
//! Creates a quaternion from a Matrix3x3
@@ -168,6 +168,14 @@ namespace AZ
float NormalizeWithLengthEstimate();
//! @}
//! Get the shortest equivalent of the rotation.
//! In case the w component of the quaternion is negative the rotation is > 180° and taking the longer path.
//! The quaternion will be inverted in that case to take the shortest path of rotation.
//! @{
Quaternion GetShortestEquivalent() const;
void ShortestEquivalent();
//! @}
//! Linearly interpolate towards a destination quaternion.
//! @param[in] dest The quaternion to interpolate towards.
//! @param[in] t Normalized interpolation value where 0.0 represents the current and 1.0 the destination value.
@@ -73,27 +73,27 @@ namespace AZ
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationX(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationX(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(sin, 0.0f, 0.0f, cos);
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationY(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationY(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(0.0f, sin, 0.0f, cos);
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationZ(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationZ(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(0.0f, 0.0f, sin, cos);
@@ -345,6 +345,23 @@ namespace AZ
}
AZ_MATH_INLINE Quaternion Quaternion::GetShortestEquivalent() const
{
if (GetW() < 0.0f)
{
return -(*this);
}
return *this;
}
AZ_MATH_INLINE void Quaternion::ShortestEquivalent()
{
*this = GetShortestEquivalent();
}
AZ_MATH_INLINE Quaternion Quaternion::Lerp(const Quaternion& dest, float t) const
{
if (Dot(dest) >= 0.0f)
+269 -275
View File
@@ -9,39 +9,38 @@
#include <AzCore/Math/Sfmt.h>
#include <AzCore/Math/Random.h>
#include <AzCore/std/parallel/lock.h>
#include <AzCore/Module/Environment.h>
#include <AzCore/std/parallel/lock.h>
#include <string.h> // for memset
namespace AZ::SfmtInternal
{
static const int N32 = N * 4;
static const int N64 = N * 2;
static const int POS1 = 122;
static const int SL1 = 18;
static const int SR1 = 11;
static const int SL2 = 1;
static const int SR2 = 1;
static const unsigned int MSK1 = 0xdfffffefU;
static const unsigned int MSK2 = 0xddfecb7fU;
static const unsigned int MSK3 = 0xbffaffffU;
static const unsigned int MSK4 = 0xbffffff6U;
static const unsigned int PARITY1 = 0x00000001U;
static const unsigned int PARITY2 = 0x00000000U;
static const unsigned int PARITY3 = 0x00000000U;
static const unsigned int PARITY4 = 0x13c9e684U;
static const int N32 = N * 4;
static const int N64 = N * 2;
static const int POS1 = 122;
static const int SL1 = 18;
static const int SR1 = 11;
static const int SL2 = 1;
static const int SR2 = 1;
static const unsigned int MSK1 = 0xdfffffefU;
static const unsigned int MSK2 = 0xddfecb7fU;
static const unsigned int MSK3 = 0xbffaffffU;
static const unsigned int MSK4 = 0xbffffff6U;
static const unsigned int PARITY1 = 0x00000001U;
static const unsigned int PARITY2 = 0x00000000U;
static const unsigned int PARITY3 = 0x00000000U;
static const unsigned int PARITY4 = 0x13c9e684U;
/** a parity check vector which certificate the period of 2^{MEXP} */
static unsigned int parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
static unsigned int parity[4] = { PARITY1, PARITY2, PARITY3, PARITY4 };
#ifdef ONLY64
# define idxof(_i) (_i ^ 1)
#define idxof(_i) (_i ^ 1)
#else
# define idxof(_i) _i
#define idxof(_i) _i
#endif // ONLY64
#if AZ_TRAIT_USE_PLATFORM_SIMD_SSE
/**
* This function represents the recursion formula.
@@ -52,7 +51,8 @@ namespace AZ::SfmtInternal
* @param mask 128-bit mask
* @return output
*/
AZ_FORCE_INLINE static Simd::Vec4::Int32Type simd_recursion(Simd::Vec4::Int32Type* a, Simd::Vec4::Int32Type* b, Simd::Vec4::Int32Type c, Simd::Vec4::Int32Type d, Simd::Vec4::Int32Type mask)
AZ_FORCE_INLINE static Simd::Vec4::Int32Type simd_recursion(
Simd::Vec4::Int32Type* a, Simd::Vec4::Int32Type* b, Simd::Vec4::Int32Type c, Simd::Vec4::Int32Type d, Simd::Vec4::Int32Type mask)
{
Simd::Vec4::Int32Type v, x, y, z;
x = *a;
@@ -151,7 +151,7 @@ namespace AZ::SfmtInternal
inline void rshift128(w128_t* out, w128_t const* in, int shift)
{
AZ::u64 th, tl, oh, ol;
#ifdef ONLY64
#ifdef ONLY64
th = ((AZ::u64)in->u[2] << 32) | ((AZ::u64)in->u[3]);
tl = ((AZ::u64)in->u[0] << 32) | ((AZ::u64)in->u[1]);
@@ -204,7 +204,7 @@ namespace AZ::SfmtInternal
#endif
}
inline void do_recursion(w128_t* r, w128_t* a, w128_t* b, w128_t* c, w128_t* d)
inline void do_recursion(w128_t* r, w128_t* a, w128_t* b, w128_t* c, w128_t* d)
{
w128_t x;
w128_t y;
@@ -229,7 +229,7 @@ namespace AZ::SfmtInternal
inline void gen_rand_all(Sfmt& g)
{
int i;
w128_t* r1, * r2;
w128_t *r1, *r2;
r1 = &g.m_sfmt[N - 2];
r2 = &g.m_sfmt[N - 1];
@@ -257,7 +257,7 @@ namespace AZ::SfmtInternal
inline void gen_rand_array(Sfmt& g, w128_t* array, int size)
{
int i, j;
w128_t* r1, * r2;
w128_t *r1, *r2;
r1 = &g.m_sfmt[N - 2];
r2 = &g.m_sfmt[N - 1];
@@ -295,82 +295,80 @@ namespace AZ::SfmtInternal
#endif
} // namespace AZ::SfmtInternal
using namespace AZ;
//////////////////////////////////////////////////////////////////////////
// Statics
//////////////////////////////////////////////////////////////////////////
static EnvironmentVariable<AZ::Sfmt> s_sfmt;
static const char* s_globalSfmtName = "GlobalSfmt";
Sfmt& Sfmt::GetInstance()
namespace AZ
{
if (!s_sfmt)
static EnvironmentVariable<AZ::Sfmt> s_sfmt;
static const char* s_globalSfmtName = "GlobalSfmt";
Sfmt& Sfmt::GetInstance()
{
s_sfmt = AZ::Environment::FindVariable<Sfmt>(s_globalSfmtName);
if (!s_sfmt)
{
Sfmt::Create();
s_sfmt = AZ::Environment::FindVariable<Sfmt>(s_globalSfmtName);
if (!s_sfmt)
{
Sfmt::Create();
}
}
return s_sfmt.Get();
}
void Sfmt::Create()
{
if (!s_sfmt)
{
s_sfmt = AZ::Environment::CreateVariable<AZ::Sfmt>(s_globalSfmtName);
}
}
return s_sfmt.Get();
}
void Sfmt::Create()
{
if (!s_sfmt)
void Sfmt::Destroy()
{
s_sfmt = AZ::Environment::CreateVariable<AZ::Sfmt>(s_globalSfmtName);
s_sfmt.Reset();
}
}
void Sfmt::Destroy()
{
s_sfmt.Reset();
}
//=========================================================================
// Sfmt
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt()
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
//=========================================================================
// Sfmt
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt()
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
Seed();
}
Seed();
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt(AZ::u32* keys, int numKeys)
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt(AZ::u32* keys, int numKeys)
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
Seed(keys, numKeys);
}
Seed(keys, numKeys);
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void
Sfmt::Seed()
{
// buffer with random values
AZ::u32 buffer[32];
BetterPseudoRandom rnd;
bool result = rnd.GetRandom(buffer, sizeof(buffer));
(void)result;
AZ_Warning("System", result, "Failed to seed properly the Smft generator!");
Seed(buffer, AZ_ARRAY_SIZE(buffer));
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void Sfmt::Seed()
{
// buffer with random values
AZ::u32 buffer[32];
BetterPseudoRandom rnd;
bool result = rnd.GetRandom(buffer, sizeof(buffer));
(void)result;
AZ_Warning("System", result, "Failed to seed properly the Smft generator!");
Seed(buffer, AZ_ARRAY_SIZE(buffer));
}
/**
* This function represents a function used in the initialization
@@ -388,226 +386,222 @@ Sfmt::Seed()
*/
#define azsfmt_func2(x) ((x ^ (x >> 27)) * (AZ::u32)1566083941UL)
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void
Sfmt::Seed(AZ::u32* keys, int numKeys)
{
using SfmtInternal::N;
using SfmtInternal::N32;
int i, j, count;
AZ::u32 r;
int lag;
int mid;
int size = N * 4;
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void Sfmt::Seed(AZ::u32* keys, int numKeys)
{
using SfmtInternal::N;
using SfmtInternal::N32;
int i, j, count;
AZ::u32 r;
int lag;
int mid;
int size = N * 4;
if (size >= 623)
{
lag = 11;
}
else if (size >= 68)
{
lag = 7;
}
else if (size >= 39)
{
lag = 5;
}
else
{
lag = 3;
}
mid = (size - lag) / 2;
if (size >= 623)
{
lag = 11;
}
else if (size >= 68)
{
lag = 7;
}
else if (size >= 39)
{
lag = 5;
}
else
{
lag = 3;
}
mid = (size - lag) / 2;
memset(m_sfmt, 0x8b, sizeof(m_sfmt));
if (numKeys + 1 > SfmtInternal::N32)
{
count = numKeys + 1;
}
else
{
count = N32;
}
r = azsfmt_func1((m_psfmt32[idxof(0)] ^ m_psfmt32[idxof(mid)] ^ m_psfmt32[idxof(N32 - 1)]));
m_psfmt32[idxof(mid)] += r;
r += numKeys;
m_psfmt32[idxof(mid + lag)] += r;
m_psfmt32[idxof(0)] = r;
memset(m_sfmt, 0x8b, sizeof(m_sfmt));
if (numKeys + 1 > SfmtInternal::N32)
{
count = numKeys + 1;
}
else
{
count = N32;
}
r = azsfmt_func1((m_psfmt32[idxof(0)] ^ m_psfmt32[idxof(mid)] ^ m_psfmt32[idxof(N32 - 1)]));
m_psfmt32[idxof(mid)] += r;
r += numKeys;
m_psfmt32[idxof(mid + lag)] += r;
m_psfmt32[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < numKeys); j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += keys[j] + i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (; j < count; j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (j = 0; j < N32; j++)
{
r = azsfmt_func2((m_psfmt32[idxof(i)] + m_psfmt32[idxof((i + mid) % N32)] + m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] ^= r;
r -= i;
m_psfmt32[idxof((i + mid + lag) % N32)] ^= r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
count--;
for (i = 1, j = 0; (j < count) && (j < numKeys); j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += keys[j] + i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (; j < count; j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (j = 0; j < N32; j++)
{
r = azsfmt_func2((m_psfmt32[idxof(i)] + m_psfmt32[idxof((i + mid) % N32)] + m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] ^= r;
r -= i;
m_psfmt32[idxof((i + mid + lag) % N32)] ^= r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
m_index = N32;
PeriodCertification();
}
m_index = N32;
PeriodCertification();
}
#undef azsfmt_func1
#undef azsfmt_func2
//=========================================================================
// PeriodCertification
// [4/10/2012]
//=========================================================================
void
Sfmt::PeriodCertification()
{
int inner = 0;
int i, j;
AZ::u32 work;
//=========================================================================
// PeriodCertification
// [4/10/2012]
//=========================================================================
void Sfmt::PeriodCertification()
{
int inner = 0;
int i, j;
AZ::u32 work;
for (i = 0; i < 4; i++)
{
inner ^= m_psfmt32[idxof(i)] & SfmtInternal::parity[i];
}
for (i = 16; i > 0; i >>= 1)
{
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1)
{
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++)
{
work = 1;
for (j = 0; j < 32; j++)
for (i = 0; i < 4; i++)
{
if ((work & SfmtInternal::parity[i]) != 0)
inner ^= m_psfmt32[idxof(i)] & SfmtInternal::parity[i];
}
for (i = 16; i > 0; i >>= 1)
{
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1)
{
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++)
{
work = 1;
for (j = 0; j < 32; j++)
{
m_psfmt32[idxof(i)] ^= work;
return;
if ((work & SfmtInternal::parity[i]) != 0)
{
m_psfmt32[idxof(i)] ^= work;
return;
}
work = work << 1;
}
work = work << 1;
}
}
}
//=========================================================================
// Rand32
// [4/10/2012]
//=========================================================================
AZ::u32 Sfmt::Rand32()
{
int index = m_index.fetch_add(1);
if (index >= SfmtInternal::N32)
//=========================================================================
// Rand32
// [4/10/2012]
//=========================================================================
AZ::u32 Sfmt::Rand32()
{
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 1; // compare against the result of fetch_add(1) above
if (m_index.compare_exchange_strong(index, 0))
int index = m_index.fetch_add(1);
if (index >= SfmtInternal::N32)
{
SfmtInternal::gen_rand_all(*this);
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 1; // compare against the result of fetch_add(1) above
if (m_index.compare_exchange_strong(index, 0))
{
SfmtInternal::gen_rand_all(*this);
}
// try again, with the new table
return Rand32();
}
// try again, with the new table
return Rand32();
return m_psfmt32[index];
}
return m_psfmt32[index];
}
//=========================================================================
// Rand64
// [4/10/2012]
//=========================================================================
AZ::u64 Sfmt::Rand64()
{
int index = m_index.fetch_add(2);
if (index >= (SfmtInternal::N32 - 1))
//=========================================================================
// Rand64
// [4/10/2012]
//=========================================================================
AZ::u64 Sfmt::Rand64()
{
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 2; // compare against the result of fetch_add(2) above
if (m_index.compare_exchange_strong(index, 0))
int index = m_index.fetch_add(2);
if (index >= (SfmtInternal::N32 - 1))
{
SfmtInternal::gen_rand_all(*this);
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 2; // compare against the result of fetch_add(2) above
if (m_index.compare_exchange_strong(index, 0))
{
SfmtInternal::gen_rand_all(*this);
}
// try again, with the new table
return Rand64();
}
// try again, with the new table
return Rand64();
AZ::u64 r;
r = m_psfmt64[index / 2];
return r;
}
AZ::u64 r;
r = m_psfmt64[index / 2];
return r;
}
//=========================================================================
// FillArray32
// [4/10/2012]
//=========================================================================
void Sfmt::FillArray32(AZ::u32* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N32, "Size must be bigger than %d GetMinArray32Size()!", SfmtInternal::N32);
//=========================================================================
// FillArray32
// [4/10/2012]
//=========================================================================
void
Sfmt::FillArray32(AZ::u32* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N32, "Size must be bigger than %d GetMinArray32Size()!", SfmtInternal::N32);
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 4);
m_index = SfmtInternal::N32;
}
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 4);
m_index = SfmtInternal::N32;
}
//=========================================================================
// FillArray64
// [4/10/2012]
//=========================================================================
void Sfmt::FillArray64(AZ::u64* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N64, "Size must be bigger than %d GetMinArray64Size()!", SfmtInternal::N64);
//=========================================================================
// FillArray64
// [4/10/2012]
//=========================================================================
void
Sfmt::FillArray64(AZ::u64* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N64, "Size must be bigger than %d GetMinArray64Size()!", SfmtInternal::N64);
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 2);
m_index = SfmtInternal::N32;
}
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 2);
m_index = SfmtInternal::N32;
}
//=========================================================================
// GetMinArray32Size
// [4/10/2012]
//=========================================================================
int Sfmt::GetMinArray32Size() const
{
return SfmtInternal::N32;
}
//=========================================================================
// GetMinArray32Size
// [4/10/2012]
//=========================================================================
int
Sfmt::GetMinArray32Size() const
{
return SfmtInternal::N32;
}
//=========================================================================
// GetMinArray64Size
// [4/10/2012]
//=========================================================================
int Sfmt::GetMinArray64Size() const
{
return SfmtInternal::N64;
}
//=========================================================================
// GetMinArray64Size
// [4/10/2012]
//=========================================================================
int
Sfmt::GetMinArray64Size() const
{
return SfmtInternal::N64;
}
} // namespace AZ
@@ -1424,7 +1424,8 @@ namespace AZ
}
}
using namespace AZ;
namespace AZ
{
#ifndef AZ_USE_CUSTOM_SCRIPT_BIND
@@ -2254,6 +2255,7 @@ LUA_API const Node* lua_getDummyNode()
}
#endif // AZ_USE_CUSTOM_SCRIPT_BIND
} // namespace AZ
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -5825,7 +5827,6 @@ LUA_API const Node* lua_getDummyNode()
AllocatorWrapper<Internal::LuaSystemAllocator> m_luaAllocator;
AZStd::thread::id m_ownerThreadId; // Check if Lua methods (including EBus handlers) are called from background threads.
};
} // namespace AZ
ScriptContext::ScriptContext(ScriptContextId id, IAllocatorAllocate* allocator, lua_State* nativeContext)
{
@@ -6116,5 +6117,6 @@ LUA_API const Node* lua_getDummyNode()
{
return m_impl->ConstructScriptProperty(sdc, valueIndex, name, restrictToPropertyArrays);
}
} // namespace AZ
#undef AZ_DBG_NAME_FIXER
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_CONTEXT_H
#define AZCORE_SCRIPT_CONTEXT_H
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/function/function_fwd.h>
@@ -1032,4 +1031,3 @@ namespace AZ
}
} // namespace AZ
#endif // AZCORE_SCRIPT_CONTEXT_H
@@ -25,10 +25,8 @@ extern "C" {
namespace AZ
{
void LuaHook(lua_State* l, lua_Debug* ar);
}
using namespace AZ;
/**
* A temp class that will override the current script context error handler and store the error (without any messages)
@@ -599,7 +597,7 @@ static ScriptContextDebug::BreakpointId MakeBreakpointId(const char* sourceName,
// LuaHook
// [6/28/2012]
//=========================================================================
void AZ::LuaHook(lua_State* l, lua_Debug* ar)
void LuaHook(lua_State* l, lua_Debug* ar)
{
// Read contexts
lua_rawgeti(l, LUA_REGISTRYINDEX, AZ_LUA_SCRIPT_CONTEXT_REF);
@@ -1543,4 +1541,6 @@ ScriptContextDebug::SetValue(const DebugValue& sourceValue)
return true;
}
} // namespace AZ
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_CONTEXT_DEBUG_H
#define AZCORE_SCRIPT_CONTEXT_DEBUG_H
#pragma once
#include <AzCore/Script/ScriptContext.h>
#include <AzCore/std/functional.h>
@@ -213,6 +212,3 @@ namespace AZ
ScriptContext& m_context;
};
}
#endif // AZCORE_SCRIPT_CONTEXT_DEBUG_H
#pragma once
@@ -31,7 +31,8 @@
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/std/string/conversions.h>
using namespace AZ;
namespace AZ
{
/**
* Script lifecycle:
@@ -44,8 +45,7 @@ using namespace AZ;
* If the script was loaded by a ScriptComponent, Load will be called once reload is complete.
*/
namespace
{
namespace LocalTU_ScriptSystemComponent {
// Called when a module has already been loaded
static int LuaRequireLoadedModule(lua_State* l)
{
@@ -54,8 +54,10 @@ namespace
return 1;
}
}
//=========================================================================
// ScriptSystemComponent
// [5/29/2012]
@@ -479,7 +481,7 @@ int ScriptSystemComponent::DefaultRequireHook(lua_State* lua, ScriptContext* con
scriptIt->second.m_scriptNames.emplace(module);
// Push the value to a closure that will just return it
lua_rawgeti(lua, LUA_REGISTRYINDEX, scriptIt->second.m_tableReference);
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// If asset reference already populated, just return now. Otherwise, capture reference
if (scriptIt->second.m_scriptAsset.GetId().IsValid())
@@ -519,7 +521,7 @@ int ScriptSystemComponent::DefaultRequireHook(lua_State* lua, ScriptContext* con
}
// Push function returning the result
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// Set asset reference on the loaded script
scriptIt = container->m_loadedScripts.find(scriptId.m_guid);
@@ -565,7 +567,7 @@ int ScriptSystemComponent::InMemoryRequireHook(lua_State* lua, ScriptContext* co
scriptIt->second.m_scriptNames.emplace(module);
// Push the value to a closure that will just return it
lua_rawgeti(lua, LUA_REGISTRYINDEX, scriptIt->second.m_tableReference);
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// If asset reference already populated, just return now. Otherwise, capture reference
if (scriptIt->second.m_scriptAsset.GetId().IsValid())
@@ -591,7 +593,7 @@ int ScriptSystemComponent::InMemoryRequireHook(lua_State* lua, ScriptContext* co
}
// Push function returning the result
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// Set asset reference on the loaded script
scriptIt = container->m_loadedScripts.find(scriptId.m_guid);
@@ -996,4 +998,5 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection)
}
}
} // namespace AZ
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#define AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/Component/TickBus.h>
@@ -182,6 +181,3 @@ namespace AZ
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
};
}
#endif // AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#pragma once
@@ -150,7 +150,7 @@ namespace AZ
{
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
StoreTypeName(classData, context), context.GetJsonAllocator());
StoreTypeName(classData, classData.m_typeId, context), context.GetJsonAllocator());
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
}
return result.Combine(StoreClass(node, object, defaultObject, classData, context));
@@ -531,7 +531,7 @@ namespace AZ
return ResolvePointerResult::ContinueProcessing;
}
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context)
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context)
{
rapidjson::Value result;
AZStd::vector<Uuid> ids = context.GetSerializeContext()->FindClassId(Crc32(classData.m_name));
@@ -544,7 +544,7 @@ namespace AZ
// Only write the Uuid for the class if there are multiple classes sharing the same name.
// In this case it wouldn't be enough to determine which class needs to be used. The
// class name is still added as a comment for be friendlier for users to read.
AZStd::string fullName = classData.m_typeId.ToString<AZStd::string>();
AZStd::string fullName = typeId.ToString<AZStd::string>();
fullName += ' ';
fullName += classData.m_name;
result.SetString(fullName.c_str(), aznumeric_caster(fullName.size()), context.GetJsonAllocator());
@@ -560,7 +560,7 @@ namespace AZ
const SerializeContext::ClassData* data = context.GetSerializeContext()->FindClassData(typeId);
if (data)
{
output = JsonSerializer::StoreTypeName(*data, context);
output = JsonSerializer::StoreTypeName(*data, typeId, context);
return context.Report(Tasks::WriteValue, Outcomes::Success, "Type id successfully stored to json value.");
}
else
@@ -580,7 +580,7 @@ namespace AZ
{
rapidjson::Value insertedObject(rapidjson::kObjectType);
insertedObject.AddMember(
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, context),
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, classData.m_typeId, context),
context.GetJsonAllocator());
for (auto& element : output.GetObject())
@@ -79,7 +79,7 @@ namespace AZ
const void*& object, const void*& defaultObject, AZStd::any& defaultObjectStorage,
const SerializeContext::ClassData*& elementClassData, const AZ::IRttiHelper& rtti, JsonSerializerContext& context);
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context);
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context);
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
const Uuid& typeId, JsonSerializerContext& context);
@@ -0,0 +1,127 @@
/*
* 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/IO/Path/Path.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/StackedString.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/Memory/SystemAllocator.h>
namespace AZ::JsonPathSerializerInternal
{
template<typename PathType>
static JsonSerializationResult::Result Load(PathType* pathValue, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
AZ_Assert(pathValue, "Expected a valid pointer to load from json value.");
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
[[fallthrough]];
case rapidjson::kNullType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. String values can't be read from arrays, objects or null.");
case rapidjson::kStringType:
{
size_t pathLength = inputValue.GetStringLength();
if (pathLength <= pathValue->Native().max_size())
{
*pathValue = PathType(AZStd::string_view(inputValue.GetString(), pathLength)).LexicallyNormal();
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read path.");
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::ReadField, JSR::Outcomes::Invalid,
ErrorString::format("Json string value is too large to fit within path type %s. It needs to be less than %zu code points",
azrtti_typeid<PathType>().template ToString<UuidString>().c_str(), pathValue->Native().max_size()));
}
default:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, "Unknown json type encountered for string value.");
}
}
template<typename PathType>
static JsonSerializationResult::Result StoreWithDefault(rapidjson::Value& outputValue, const PathType* pathValue,
const PathType* defaultPathValue, JsonSerializerContext& context)
{
namespace JSR = JsonSerializationResult; // Removes name conflicts in AzCore in uber builds.
if (context.ShouldKeepDefaults() || defaultPathValue == nullptr || *pathValue != *defaultPathValue)
{
auto posixPathString = pathValue->AsPosix();
outputValue.SetString(posixPathString.c_str(), aznumeric_caster(posixPathString.size()), context.GetJsonAllocator());
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Path successfully stored.");
}
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default Path used.");
}
}
namespace AZ
{
AZ_CLASS_ALLOCATOR_IMPL(JsonPathSerializer, SystemAllocator, 0);
JsonSerializationResult::Result JsonPathSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
if (outputValueTypeId == azrtti_typeid<AZ::IO::Path>())
{
return JsonPathSerializerInternal::Load(reinterpret_cast<AZ::IO::Path*>(outputValue), inputValue,
context);
}
else if (outputValueTypeId == azrtti_typeid<AZ::IO::FixedMaxPath>())
{
return JsonPathSerializerInternal::Load(reinterpret_cast<AZ::IO::FixedMaxPath*>(outputValue), inputValue,
context);
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
auto errorTypeIdString = outputValueTypeId.ToString<UuidString>();
AZ_Assert(false, "Unable to serialize json string"
" to a path of type %s", errorTypeIdString.c_str());
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::TypeMismatch,
ErrorString::format("Output value type ID %s is not a valid Path type", errorTypeIdString.c_str()));
}
JsonSerializationResult::Result JsonPathSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context)
{
if (valueTypeId == azrtti_typeid<AZ::IO::Path>())
{
return JsonPathSerializerInternal::StoreWithDefault(outputValue,
reinterpret_cast<const AZ::IO::Path*>(inputValue),
reinterpret_cast<const AZ::IO::Path*>(defaultValue), context);
}
else if (valueTypeId == azrtti_typeid<AZ::IO::FixedMaxPath>())
{
return JsonPathSerializerInternal::StoreWithDefault(outputValue,
reinterpret_cast<const AZ::IO::FixedMaxPath*>(inputValue),
reinterpret_cast<const AZ::IO::FixedMaxPath*>(defaultValue), context);
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
auto errorTypeIdString = valueTypeId.ToString<UuidString>();
AZ_Assert(false, "Unable to serialize path type %s to a json string",
errorTypeIdString.c_str());
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::WriteValue, JsonSerializationResult::Outcomes::TypeMismatch,
ErrorString::format("Input value type ID %s is not a valid Path type", errorTypeIdString.c_str()));
}
} // namespace AZ
@@ -0,0 +1,26 @@
/*
* 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/Serialization/Json/BaseJsonSerializer.h>
namespace AZ
{
class JsonPathSerializer
: public BaseJsonSerializer
{
public:
AZ_RTTI(JsonPathSerializer, "{F6FBA901-07E0-4F03-A0B6-72A9A6CE1E96}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
} // namespace AZ
@@ -537,6 +537,8 @@ set(FILES
Serialization/Json/JsonUtils.cpp
Serialization/Json/MapSerializer.h
Serialization/Json/MapSerializer.cpp
Serialization/Json/PathSerializer.h
Serialization/Json/PathSerializer.cpp
Serialization/Json/RegistrationContext.h
Serialization/Json/RegistrationContext.cpp
Serialization/Json/SmartPointerSerializer.h
@@ -11,6 +11,7 @@
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@@ -453,7 +454,7 @@ namespace UnitTest
AZ::Quaternion backFromScaledAxisAngle = AZ::Quaternion::CreateFromScaledAxisAngle(scaledAxisAngle);
// Compare the original quaternion with the one after the conversion.
EXPECT_TRUE(testQuat.IsClose(backFromScaledAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromScaledAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, AxisAngleQuatRoundtripTests)
@@ -467,7 +468,7 @@ namespace UnitTest
// Convert the axis-angle back into a quaternion and compare the original quaternion with the one after the conversion.
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axis, angle);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareAxisAngleConversionTests)
@@ -506,8 +507,20 @@ namespace UnitTest
}
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axisFromScaledResult, angleFromScaledResult);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
INSTANTIATE_TEST_CASE_P(MATH_Quaternion, QuaternionScaledAxisAngleConversionFixture, ::testing::ValuesIn(RotationRepresentationConversionTestQuats));
TEST(MATH_Quaternion, ShortestEquivalent)
{
const AZ::Quaternion testQuat = AZ::Quaternion::CreateRotationX(AZ::Constants::HalfPi * 3.0f);
AZ::Quaternion absQuat = testQuat;
absQuat.ShortestEquivalent();
EXPECT_THAT(testQuat.GetShortestEquivalent(), IsCloseTolerance(absQuat, 1e-6f));
const float angle = absQuat.GetEulerRadians().GetX();
EXPECT_THAT(angle, testing::FloatEq(-AZ::Constants::HalfPi));
}
}
@@ -0,0 +1,106 @@
/*
* 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/IO/Path/Path.h>
#include <AzCore/IO/Path/PathReflect.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
namespace JsonSerializationTests
{
template<typename PathType>
class PathTestDescription
: public JsonSerializerConformityTestDescriptor<PathType>
{
public:
using JsonSerializerConformityTestDescriptor<PathType>::Reflect;
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
{
AZ::IO::PathReflect(serializeContext.get());
}
void Reflect(AZStd::unique_ptr<AZ::JsonRegistrationContext>& jsonContext) override
{
AZ::IO::PathReflect(jsonContext.get());
}
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
{
return AZStd::make_shared<AZ::JsonPathSerializer>();
}
AZStd::shared_ptr<PathType> CreateDefaultInstance() override
{
return AZStd::make_shared<PathType>();
}
AZStd::shared_ptr<PathType> CreateFullySetInstance() override
{
return AZStd::make_shared<PathType>("O3DE/Relative/Path");
}
AZStd::string_view GetJsonForFullySetInstance() override
{
return R"("O3DE/Relative/Path")";
}
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
{
features.EnableJsonType(rapidjson::kStringType);
features.m_supportsPartialInitialization = false;
features.m_supportsInjection = false;
}
bool AreEqual(const PathType& lhs, const PathType& rhs) override
{
return lhs == rhs;
}
};
using PathConformityTestTypes = ::testing::Types<
PathTestDescription<AZ::IO::Path>,
PathTestDescription<AZ::IO::FixedMaxPath>
>;
INSTANTIATE_TYPED_TEST_CASE_P(Path, JsonSerializerConformityTests, PathConformityTestTypes);
class PathSerializerTests
: public BaseJsonSerializerFixture
{
public:
AZStd::unique_ptr<AZ::JsonPathSerializer> m_serializer;
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
m_serializer = AZStd::make_unique<AZ::JsonPathSerializer>();
}
void TearDown() override
{
m_serializer.reset();
BaseJsonSerializerFixture::TearDown();
}
};
TEST_F(PathSerializerTests, LoadingIntoFixedMaxPath_GreaterThanMaxPathLength_Fails)
{
AZ::IO::Path testPath;
// Fill a path greater than the AZ::IO::MaxPathLength in write it to Json
testPath.Native().append(AZ::IO::MaxPathLength + 2, 'a');
rapidjson::Value loadPathValue;
AZ::JsonSerializationResult::ResultCode resultCode = m_serializer->Store(loadPathValue,
&testPath, nullptr, azrtti_typeid<AZ::IO::Path>(), *m_jsonSerializationContext);
EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Success, resultCode.GetOutcome());
AZ::IO::FixedMaxPath resultPath;
AZ::JsonSerializationResult::ResultCode result = m_serializer->Load(&resultPath, azrtti_typeid<AZ::IO::FixedMaxPath>(),
loadPathValue, *m_jsonDeserializationContext);
EXPECT_GE(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::Invalid);
}
} // namespace JsonSerializationTests
@@ -10,6 +10,77 @@
#include <Tests/Serialization/Json/JsonSerializationTests.h>
#include <Tests/Serialization/Json/TestCases_Classes.h>
#include <Tests/Serialization/Json/TestCases_Pointers.h>
#include <AzCore/Asset/AssetCommon.h>
namespace AZ
{
template<typename T>
struct SerializeGenericTypeInfo<JsonSerializationTests::TemplatedClass<T>>
{
using ThisType = JsonSerializationTests::TemplatedClass<T>;
class GenericTemplatedClassInfo : public GenericClassInfo
{
public:
GenericTemplatedClassInfo()
: m_classData{ SerializeContext::ClassData::Create<ThisType>(
"TemplatedClass", "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", nullptr, nullptr) }
{
}
SerializeContext::ClassData* GetClassData() override
{
return &m_classData;
}
size_t GetNumTemplatedArguments() override
{
return 1;
}
const Uuid& GetSpecializedTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetGenericTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetTemplatedTypeId(size_t element) override
{
(void)element;
return SerializeGenericTypeInfo<T>::GetClassTypeId();
}
void Reflect(SerializeContext* serializeContext) override
{
if (serializeContext)
{
serializeContext->RegisterGenericClassInfo(
GetSpecializedTypeId(), this, &AZ::AnyTypeInfoConcept<Data::Asset<Data::AssetData>>::CreateAny);
serializeContext->RegisterGenericClassInfo(
azrtti_typeid<ThisType>(), this,
&AZ::AnyTypeInfoConcept<ThisType>::CreateAny);
}
}
SerializeContext::ClassData m_classData;
};
using ClassInfoType = GenericTemplatedClassInfo;
static ClassInfoType* GetGenericInfo()
{
return GetCurrentSerializeContextModule().CreateGenericClassInfo<ThisType>();
}
static const Uuid& GetClassTypeId()
{
return GetGenericInfo()->GetClassData()->m_typeId;
}
};
} // namespace AZ
namespace JsonSerializationTests
{
@@ -286,4 +357,32 @@ namespace JsonSerializationTests
EXPECT_EQ(Processing::Halted, result.GetProcessing());
EXPECT_EQ(Outcomes::Unknown, result.GetOutcome());
}
TEST_F(JsonSerializationTests, StoreTypeId_TemplatedType_StoresUuidWithName)
{
using namespace AZ;
using namespace AZ::JsonSerializationResult;
m_serializeContext->RegisterGenericType<TemplatedClass<A::Inherited>>();
m_serializeContext->RegisterGenericType<TemplatedClass<BaseClass>>();
Uuid input = azrtti_typeid<TemplatedClass<A::Inherited>>();
ResultCode result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
AZStd::string expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<A::Inherited>>().ToString<AZStd::string>().c_str());
Expect_DocStrEq(expected.c_str(), false);
input = azrtti_typeid<TemplatedClass<BaseClass>>();
result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<BaseClass>>().ToString<AZStd::string>().c_str());
EXPECT_EQ(Processing::Completed, result.GetProcessing());
Expect_DocStrEq(expected.c_str(), false);
}
} // namespace JsonSerializationTests
@@ -76,192 +76,4 @@ namespace UnitTest
int64_t delta = static_cast<int64_t>(timeMs) - static_cast<int64_t>(timeUsToMs);
EXPECT_LT(abs(delta), 1);
}
class TimeSystemTests : public AllocatorsTestFixture
{
public:
void SetUp() override
{
SetupAllocator();
m_controlTime = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
m_timeSystem = AZStd::make_unique<AZ::TimeSystem>();
}
void TearDown() override
{
m_controlTime = AZ::Time::ZeroTimeUs;
m_timeSystem.reset();
TeardownAllocator();
}
AZ::TimeUs GetDiff(AZ::TimeUs time1, AZ::TimeUs time2) const
{
// AZ::TimeUs is unsigned so make sure to not underflow.
return time1 > time2 ? time1 - time2 : time2 - time1;
}
AZ::TimeUs m_controlTime;
AZStd::unique_ptr<AZ::TimeSystem> m_timeSystem;
};
TEST_F(TimeSystemTests, GetRealElapsedTimeUs)
{
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetRealElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetRealElapsedTimeUs();
const AZ::TimeUs diff = GetDiff(baseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, GetElapsedTimeUs)
{
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetElapsedTimeUs();
const AZ::TimeUs diff = GetDiff(baseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, ElapsedTimeScales)
{
// slow down 'time'
m_timeSystem->SetSimulationTickScale(0.5f);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetElapsedTimeUs();
const AZ::TimeUs halfBaseline = (baseline / AZ::TimeUs{ 2 });
// elapsedTime should be about half of the control.
const AZ::TimeUs diff = GetDiff(halfBaseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset time scale
m_timeSystem->SetSimulationTickScale(1.0f);
}
TEST_F(TimeSystemTests, AdvanceTickDeltaTimes)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be close to the baselineDelta.
const AZ::TimeUs diff = GetDiff(delta, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, SimulationAndRealTickDeltaTimesWithNoTimeScale)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be close to the baselineDelta.
AZ::TimeUs diff = GetDiff(delta, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// the delta should be the same as GetSimulationTickDeltaTimeUs and near GetRealTickDeltaTimeUs
const AZ::TimeUs simDeltaTime = m_timeSystem->GetSimulationTickDeltaTimeUs();
EXPECT_EQ(delta, simDeltaTime);
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
diff = GetDiff(delta, realDeltaTime);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, SimulationAndRealTickDeltaTimesWithTimeScale)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// slow down 'time';
m_timeSystem->SetSimulationTickScale(0.5f);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
const AZ::TimeUs halfBaselineDelta = (baselineDelta / AZ::TimeUs{ 2 });
// the delta should be half the baselineDelta
AZ::TimeUs diff = GetDiff(delta, halfBaselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// the delta should be the same as GetSimulationTickDeltaTimeUs
const AZ::TimeUs simDeltaTime = m_timeSystem->GetSimulationTickDeltaTimeUs();
EXPECT_EQ(delta, simDeltaTime);
// the delta should be near half the GetRealTickDeltaTimeUs
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
const AZ::TimeUs halfRealDeltaTime = (realDeltaTime / AZ::TimeUs{ 2 });
diff = GetDiff(delta, halfRealDeltaTime);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset time scale
m_timeSystem->SetSimulationTickScale(1.0f);
}
TEST_F(TimeSystemTests, SimulationTickDeltaOverride)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// set the tick delta override
const AZ::TimeMs tickOverride = AZ::TimeMs{ 3462 };
m_timeSystem->SetSimulationTickDeltaOverride(tickOverride);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be equal to the tickOverride
EXPECT_EQ(delta, AZ::TimeMsToUs(tickOverride));
// real tick delta should be near the baselineDelta
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
const AZ::TimeUs diff = GetDiff(realDeltaTime, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset the tick delta override
m_timeSystem->SetSimulationTickDeltaOverride(AZ::Time::ZeroTimeMs);
}
} // namespace UnitTest
@@ -111,6 +111,7 @@ set(FILES
Serialization/Json/MapSerializerTests.cpp
Serialization/Json/MathVectorSerializerTests.cpp
Serialization/Json/MathMatrixSerializerTests.cpp
Serialization/Json/PathSerializerTests.cpp
Serialization/Json/SmartPointerSerializerTests.cpp
Serialization/Json/StringSerializerTests.cpp
Serialization/Json/TestCases.h
@@ -270,8 +270,6 @@ set(FILES
Physics/WindBus.h
Process/ProcessCommunicator.cpp
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
Process/ProcessWatcher.h
Process/ProcessCommon_fwd.h
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
@@ -83,4 +83,9 @@ namespace AzFramework
{
}
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
{
return AZStd::string{};
}
} //namespace AzFramework
@@ -243,7 +243,7 @@ SliderDoubleCombo::SliderDoubleCombo(QWidget* parent)
InitialiseSliderCombo(this, layout, m_spinbox, m_slider);
connect(m_slider, &SliderDouble::valueChanged, this, &SliderDoubleCombo::setValue);
connect(m_slider, &SliderDouble::valueChanged, this, &SliderDoubleCombo::setValueSlider);
connect(m_spinbox, QOverload<double>::of(&DoubleSpinBox::valueChanged), this, &SliderDoubleCombo::setValue);
connect(m_slider, &SliderDouble::sliderReleased, this, &SliderDoubleCombo::editingFinished);
connect(m_spinbox, &DoubleSpinBox::editingFinished, this, &SliderDoubleCombo::editingFinished);
@@ -254,7 +254,7 @@ SliderDoubleCombo::~SliderDoubleCombo()
{
}
void SliderDoubleCombo::setValue(double value)
void SliderDoubleCombo::setValueSlider(double value)
{
const bool doEmit = m_value != value;
m_value = value;
@@ -264,10 +264,34 @@ void SliderDoubleCombo::setValue(double value)
if (doEmit)
{
// We don't want to update the slider from setValue as this
// causes rounding errors in the tooltip hint.
m_fromSlider = true;
Q_EMIT valueChanged();
}
}
void SliderDoubleCombo::setValue(double value)
{
const bool doEmit = m_value != value;
m_value = value;
updateSpinBox();
if (!m_fromSlider)
{
updateSlider();
if (doEmit)
{
Q_EMIT valueChanged();
}
}
else
{
m_fromSlider = false;
}
}
SliderDouble* SliderDoubleCombo::slider() const
{
return m_slider;
@@ -151,6 +151,8 @@ namespace AzQtComponents
//! Sets the current value.
void setValue(double value);
//! Sets the current value.
void setValueSlider(double value);
//! Return the current value.
Q_REQUIRED_RESULT double value() const;
@@ -235,5 +237,6 @@ namespace AzQtComponents
double m_softMinimum = 0.0;
double m_softMaximum = 100.0;
double m_value = 0.0;
bool m_fromSlider{ false };
};
} // namespace AzQtComponents
@@ -144,7 +144,10 @@ namespace AzToolsFramework
{
emit ClearStringFilter();
emit ClearTypeFilter();
m_sourceFilterModel->FilterUpdatedSlotImmediate();
if (m_sourceFilterModel)
{
m_sourceFilterModel->FilterUpdatedSlotImmediate();
}
}
void AssetBrowserTableView::Update()
@@ -2666,19 +2666,15 @@ namespace AzToolsFramework
if (!isPathSafeForAssets)
{
// Put an error in the console, so the log files have info about this error, or the user can look up the error after dismissing it.
AZStd::string errorMessage = "You can save slices only to your game project folder or the Gems folder. Update the location and try again.\n\n"
"You can also review and update your save locations in the AssetProcessorPlatformConfig.ini file.";
AZStd::string errorMessage = "You can save slices only to your game project folder or the Gems folder. Update the location and try again.\n\n";
AZ_Error("Slice", false, errorMessage.c_str());
QString learnMoreLink(QObject::tr(""));
QString learnMoreDescription(QObject::tr(" <a href='%1'>Learn more</a>").arg(learnMoreLink));
// Display a pop-up, the logs are easy to miss. This will make sure a user who encounters this error immediately knows their slice save has failed.
QMessageBox msgBox(activeWindow);
msgBox.setIcon(QMessageBox::Icon::Warning);
msgBox.setTextFormat(Qt::RichText);
msgBox.setWindowTitle(QObject::tr("Invalid save location"));
msgBox.setText(QString("%1 %2").arg(QObject::tr(errorMessage.c_str())).arg(learnMoreDescription));
msgBox.setText(QString("%1").arg(QObject::tr(errorMessage.c_str())));
msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Retry);
msgBox.setDefaultButton(QMessageBox::Retry);
const int response = msgBox.exec();
@@ -2689,7 +2685,16 @@ namespace AzToolsFramework
// so set the suggested save path to a known valid location.
if (assetSafeFolders.size() > 0)
{
retrySavePath = assetSafeFolders[0];
QStringList strList = slicePath.split("/");
if (strList.size() > 0)
{
retrySavePath = assetSafeFolders[0] + ("/" + strList[strList.size() - 1]).toUtf8().data();
}
else
{
retrySavePath = assetSafeFolders[0];
}
}
return SliceSaveResult::Retry;
case QMessageBox::Cancel:
@@ -840,8 +840,6 @@ namespace AzToolsFramework
richLabel->setTextFormat(Qt::RichText);
}
richLabel->setText(data);
richLabel->setGeometry(options.rect);
richLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
richLabel->setPalette(options.palette);
@@ -1117,6 +1117,8 @@ namespace AzToolsFramework
m_listModel->SearchStringChanged(filterString);
m_proxyModel->UpdateFilter();
m_gui->m_objectTree->expandAll();
}
void EntityOutlinerWidget::OnFilterChanged(const AzQtComponents::SearchTypeFilterList& activeTypeFilters)
@@ -10,7 +10,7 @@
#if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
#include <AzCore/PlatformDef.h>
#include <AzCore/PlatformIncl.h>
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
#include <aws/core/utils/logging/LogSystemInterface.h>
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/PlatformIncl.h>
#if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
#include <aws/core/utils/memory/MemorySystemInterface.h>
#else
@@ -13,7 +13,7 @@
#include <AzCore/Module/Environment.h>
#if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
#include <AzCore/PlatformIncl.h>
// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly.
// AWSAllocator.h(70): warning C4996: 'std::allocator<T>::pointer': warning STL4010: Various members of std::allocator are deprecated in C++17.
// Use std::allocator_traits instead of accessing these members directly.
@@ -37,6 +37,7 @@
#include <AssetBuilderInfo.h>
#include <AzCore/Interface/Interface.h>
#include <Entity/EntityUtilityComponent.h>
#include <AssetBuilderStatic.h>
namespace AssetBuilder
{
@@ -165,6 +166,7 @@ void AssetBuilderApplication::StartCommon(AZ::Entity* systemEntity)
AssetBuilderSDK::InitializeSerializationContext();
AssetBuilderSDK::InitializeBehaviorContext();
AssetBuilder::InitializeSerializationContext();
// the asset builder app never writes source files, only assets, so there is no need to do any kind of asset upgrading
AZ::Data::AssetManager::Instance().SetAssetInfoUpgradingEnabled(false);
@@ -34,6 +34,7 @@
#include <AzCore/Interface/Interface.h>
#include <AzFramework/Asset/AssetSystemComponent.h>
#include <ToolsComponents/ToolsAssetCatalogComponent.h>
#include <AssetBuilderStatic.h>
// Command-line parameter options:
static const char* const s_paramHelp = "help"; // Print help information.
@@ -51,10 +52,10 @@ static const char* const s_paramDebugCreate = "debug_create"; // Debug mode for
static const char* const s_paramDebugProcess = "debug_process"; // Debug mode for the process job of the specified file.
static const char* const s_paramPlatformTags = "tags"; // Additional list of tags to add platform tag list.
static const char* const s_paramPlatform = "platform"; // Platform to use
static const char* const s_paramRegisterBuilders = "register"; // Indicates the AP is starting up and requesting a list of registered builders
// Task modes:
static const char* const s_taskResident = "resident"; // stays up and running indefinitely, accepting jobs via network connection
static const char* const s_taskRegisterBuilder = "register"; // outputs all the builder descriptors
static const char* const s_taskCreateJob = "create"; // runs a builders createJobs function
static const char* const s_taskProcessJob = "process"; // runs processJob function
static const char* const s_taskDebug = "debug"; // runs a one shot job in a fake environment for a specified file.
@@ -204,6 +205,40 @@ void AssetBuilderComponent::Reflect(AZ::ReflectContext* context)
}
}
bool AssetBuilderComponent::DoHelloPing()
{
using namespace AssetBuilder;
BuilderHelloRequest request;
BuilderHelloResponse response;
AZStd::string id;
if (!GetParameter(s_paramId, id))
{
return false;
}
request.m_uuid = AZ::Uuid::CreateString(id.c_str());
AZ_TracePrintf(
"AssetBuilderComponent", "RunInResidentMode: Pinging asset processor with the builder UUID %s\n",
request.m_uuid.ToString<AZStd::string>().c_str());
bool result = AzFramework::AssetSystem::SendRequest(request, response);
AZ_Error("AssetBuilder", result, "Failed to send hello request to Asset Processor");
// This error is only shown if we successfully got a response AND the response explicitly indicates the AP rejected the builder
AZ_Error("AssetBuilder", !result || response.m_accepted, "Asset Processor rejected connection request");
if (result)
{
AZ_TracePrintf("AssetBuilder", "Builder ID: %s\n", response.m_uuid.ToString<AZStd::string>().c_str());
}
return result;
}
bool AssetBuilderComponent::Run()
{
AZ_TracePrintf("AssetBuilderComponent", "Run: Parsing command line.\n");
@@ -217,8 +252,8 @@ bool AssetBuilderComponent::Run()
}
AZStd::string task;
AZStd::string debugFile;
if (GetParameter(s_paramDebug, debugFile, false))
{
task = s_taskDebug;
@@ -256,11 +291,13 @@ bool AssetBuilderComponent::Run()
AZ_TracePrintf("AssetBuilderComponent", "Run: Connecting back to Asset Processor...\n");
bool connectedToAssetProcessor = ConnectToAssetProcessor();
//AP connection is required to access the asset catalog
AZ_Error("AssetBuilder", connectedToAssetProcessor, "Failed to establish a network connection to the AssetProcessor. Use -help for options.");;
AZ_Error("AssetBuilder", connectedToAssetProcessor, "Failed to establish a network connection to the AssetProcessor. Use -help for options.");
bool registerBuilders = commandLine->GetNumSwitchValues(s_paramRegisterBuilders) > 0;
IBuilderApplication* builderApplication = AZ::Interface<IBuilderApplication>::Get();
if(!builderApplication)
if (!builderApplication)
{
AZ_Error("AssetBuilder", false, "Failed to retreive IBuilderApplication interface");
return false;
@@ -274,7 +311,7 @@ bool AssetBuilderComponent::Run()
{
if (task == s_taskResident)
{
result = RunInResidentMode();
result = RunInResidentMode(registerBuilders);
}
else if (task == s_taskDebug)
{
@@ -370,43 +407,46 @@ bool AssetBuilderComponent::ConnectToAssetProcessor()
//////////////////////////////////////////////////////////////////////////
bool AssetBuilderComponent::RunInResidentMode()
bool AssetBuilderComponent::SendRegisteredBuildersToAp()
{
using namespace AssetBuilderSDK;
AssetBuilder::BuilderRegistrationRequest registrationRequest;
for (const auto& [uuid, desc] : m_assetBuilderDescMap)
{
AssetBuilder::BuilderRegistration registration;
registration.m_name = desc->m_name;
registration.m_analysisFingerprint = desc->m_analysisFingerprint;
registration.m_flags = desc->m_flags;
registration.m_flagsByJobKey = desc->m_flagsByJobKey;
registration.m_version = desc->m_version;
registration.m_busId = desc->m_busId;
registration.m_patterns = desc->m_patterns;
registration.m_productsToKeepOnFailure = desc->m_productsToKeepOnFailure;
registrationRequest.m_builders.push_back(AZStd::move(registration));
}
bool result = SendRequest(registrationRequest);
AZ_Error("AssetBuilder", result, "Failed to send builder registration request to Asset Processor");
return result;
}
bool AssetBuilderComponent::RunInResidentMode(bool sendRegistration)
{
using namespace AssetBuilder;
using namespace AZStd::placeholders;
AZ_TracePrintf("AssetBuilderComponent", "RunInResidentMode: Starting resident mode (waiting for commands to arrive)\n");
AZStd::string port, id, builderFolder;
if (!GetParameter(s_paramId, id)
|| !GetParameter(s_paramModule, builderFolder))
{
return false;
}
if (!LoadBuilders(builderFolder))
{
return false;
}
AzFramework::SocketConnection::GetInstance()->AddMessageHandler(CreateJobsNetRequest::MessageType(), AZStd::bind(&AssetBuilderComponent::CreateJobsResidentHandler, this, _1, _2, _3, _4));
AzFramework::SocketConnection::GetInstance()->AddMessageHandler(ProcessJobNetRequest::MessageType(), AZStd::bind(&AssetBuilderComponent::ProcessJobResidentHandler, this, _1, _2, _3, _4));
BuilderHelloRequest request;
BuilderHelloResponse response;
bool result = DoHelloPing() && ((sendRegistration && SendRegisteredBuildersToAp()) || !sendRegistration);
request.m_uuid = AZ::Uuid::CreateString(id.c_str());
AZ_TracePrintf("AssetBuilderComponent", "RunInResidentMode: Pinging asset processor with the builder UUID %s\n", request.m_uuid.ToString<AZStd::string>().c_str());
bool result = AzFramework::AssetSystem::SendRequest(request, response);
AZ_Error("AssetBuilder", result, "Failed to send hello request to Asset Processor");
// This error is only shown if we successfully got a response AND the response explicitly indicates the AP rejected the builder
AZ_Error("AssetBuilder", !result || response.m_accepted, "Asset Processor rejected connection request");
if (result && response.m_accepted)
if (result)
{
m_running = true;
@@ -415,7 +455,6 @@ bool AssetBuilderComponent::RunInResidentMode()
AzFramework::EngineConnectionEvents::Bus::Handler::BusConnect(); // Listen for disconnects
AZ_TracePrintf("AssetBuilder", "Builder ID: %s\n", response.m_uuid.ToString<AZStd::string>().c_str());
AZ_TracePrintf("AssetBuilder", "Resident mode ready\n");
m_mainEvent.acquire();
AZ_TracePrintf("AssetBuilder", "Shutting down\n");
@@ -736,11 +775,7 @@ bool AssetBuilderComponent::RunOneShotTask(const AZStd::string& task)
AZ::StringFunc::Path::Normalize(inputFilePath);
AZ::StringFunc::Path::Normalize(outputFilePath);
if (task == s_taskRegisterBuilder)
{
return HandleRegisterBuilder(inputFilePath, outputFilePath);
}
else if (task == s_taskCreateJob)
if (task == s_taskCreateJob)
{
auto func = [this](const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response)
{
@@ -896,7 +931,7 @@ void AssetBuilderComponent::JobThread()
{
case JobType::Create:
{
using namespace AssetBuilderSDK;
using namespace AssetBuilder;
auto* netRequest = azrtti_cast<CreateJobsNetRequest*>(job->m_netRequest.get());
auto* netResponse = azrtti_cast<CreateJobsNetResponse*>(job->m_netResponse.get());
@@ -922,7 +957,7 @@ void AssetBuilderComponent::JobThread()
}
case JobType::Process:
{
using namespace AssetBuilderSDK;
using namespace AssetBuilder;
AZ_TracePrintf("AssetBuilder", "Running processJob task\n");
@@ -981,14 +1016,14 @@ void AssetBuilderComponent::JobThread()
void AssetBuilderComponent::CreateJobsResidentHandler(AZ::u32 /*typeId*/, AZ::u32 serial, const void* data, AZ::u32 dataLength)
{
using namespace AssetBuilderSDK;
using namespace AssetBuilder;
ResidentJobHandler<CreateJobsNetRequest, CreateJobsNetResponse>(serial, data, dataLength, JobType::Create);
}
void AssetBuilderComponent::ProcessJobResidentHandler(AZ::u32 /*typeId*/, AZ::u32 serial, const void* data, AZ::u32 dataLength)
{
using namespace AssetBuilderSDK;
using namespace AssetBuilder;
ResidentJobHandler<ProcessJobNetRequest, ProcessJobNetResponse>(serial, data, dataLength, JobType::Process);
}
@@ -1018,18 +1053,6 @@ bool AssetBuilderComponent::HandleTask(const AZStd::string& inputFilePath, const
return true;
}
bool AssetBuilderComponent::HandleRegisterBuilder(const AZStd::string& /*inputFilePath*/, const AZStd::string& outputFilePath) const
{
AssetBuilderSDK::RegisterBuilderResponse response;
for (const auto& pair : m_assetBuilderDescMap)
{
response.m_assetBuilderDescList.push_back(*pair.second);
}
return AZ::Utils::SaveObjectToFile(outputFilePath, AZ::DataStream::ST_XML, &response);
}
void AssetBuilderComponent::UpdateResultCode(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const
{
if (request.m_jobDescription.m_failOnError)
@@ -46,6 +46,7 @@ class AssetBuilderComponent
public:
AZ_COMPONENT(AssetBuilderComponent, "{04332899-5d73-4d41-86b7-b1017d349673}")
static void Reflect(AZ::ReflectContext* context);
bool DoHelloPing();
AssetBuilderComponent() = default;
~AssetBuilderComponent() override = default;
@@ -64,7 +65,7 @@ public:
void RegisterBuilderInformation(const AssetBuilderSDK::AssetBuilderDesc& builderDesc) override;
void RegisterComponentDescriptor(AZ::ComponentDescriptor* descriptor) override;
//EngineConnectionEvents Handler
void Disconnected(AzFramework::SocketConnection* connection) override;
@@ -98,12 +99,13 @@ protected:
static const char* GetLibraryExtension();
bool ConnectToAssetProcessor();
bool SendRegisteredBuildersToAp();
bool LoadBuilders(const AZStd::string& builderFolder);
bool LoadBuilder(const AZStd::string& filePath);
void UnloadBuilders();
//! Hooks up net job request handling and keeps the AssetBuilder running indefinitely
bool RunInResidentMode();
bool RunInResidentMode(bool sendRegistration);
bool RunDebugTask(AZStd::string&& debugFile, bool runCreateJobs, bool runProcessJob);
bool RunOneShotTask(const AZStd::string& task);
@@ -120,9 +122,6 @@ protected:
void ProcessJob(const AssetBuilderSDK::ProcessJobFunction& job, const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& outResponse);
//! Handles a builder registration request
bool HandleRegisterBuilder(const AZStd::string& inputFilePath, const AZStd::string& outputFilePath) const;
//! If needed looks at collected data and updates the result code from the job accordingly.
void UpdateResultCode(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const;
@@ -141,7 +140,7 @@ protected:
//! Currently loading builder
AssetBuilder::ExternalModuleAssetBuilderInfo* m_currentAssetBuilder = nullptr;
//! Thread for running a job, so we don't block the network thread while doing work
AZStd::thread_desc m_jobThreadDesc;
AZStd::thread m_jobThread;
@@ -153,7 +152,7 @@ protected:
AZStd::binary_semaphore m_mainEvent;
//! Use to signal a new job is ready to be processed
AZStd::binary_semaphore m_jobEvent;
//! Lock for m_queuedJob
AZStd::mutex m_jobMutex;
@@ -0,0 +1,182 @@
/*
* 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 <AssetBuilderStatic.h>
#include <AzCore/Component/ComponentApplicationBus.h>
namespace AssetBuilder
{
void Reflect(AZ::ReflectContext* context)
{
BuilderRegistrationRequest::Reflect(context);
BuilderHelloRequest::Reflect(context);
BuilderHelloResponse::Reflect(context);
CreateJobsNetRequest::Reflect(context);
CreateJobsNetResponse::Reflect(context);
ProcessJobNetRequest::Reflect(context);
ProcessJobNetResponse::Reflect(context);
}
void InitializeSerializationContext()
{
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ_Assert(serializeContext, "Unable to retrieve serialize context.");
Reflect(serializeContext);
}
void BuilderHelloRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderHelloRequest>()->Version(1)->Field("UUID", &BuilderHelloRequest::m_uuid);
}
}
unsigned int BuilderHelloRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::BuilderHelloRequest", 0x213a7248);
return messageType;
}
unsigned int BuilderHelloRequest::GetMessageType() const
{
return MessageType();
}
void BuilderHelloResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderHelloResponse>()
->Version(1)
->Field("Accepted", &BuilderHelloResponse::m_accepted)
->Field("UUID", &BuilderHelloResponse::m_uuid);
}
}
unsigned int BuilderHelloResponse::GetMessageType() const
{
return BuilderHelloRequest::MessageType();
}
//////////////////////////////////////////////////////////////////////////
void CreateJobsNetRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<CreateJobsNetRequest>()->Version(1)->Field("Request", &CreateJobsNetRequest::m_request);
}
}
unsigned int CreateJobsNetRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::CreateJobsNetRequest", 0xc48209c0);
return messageType;
}
unsigned int CreateJobsNetRequest::GetMessageType() const
{
return MessageType();
}
void CreateJobsNetResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<CreateJobsNetResponse>()->Version(1)->Field("Response", &CreateJobsNetResponse::m_response);
}
}
unsigned int CreateJobsNetResponse::GetMessageType() const
{
return CreateJobsNetRequest::MessageType();
}
void ProcessJobNetRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<ProcessJobNetRequest>()->Version(1)->Field("Request", &ProcessJobNetRequest::m_request);
}
}
unsigned int ProcessJobNetRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::ProcessJobNetRequest", 0x479f340f);
return messageType;
}
unsigned int ProcessJobNetRequest::GetMessageType() const
{
return MessageType();
}
void ProcessJobNetResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<ProcessJobNetResponse>()->Version(1)->Field("Response", &ProcessJobNetResponse::m_response);
}
}
unsigned int ProcessJobNetResponse::GetMessageType() const
{
return ProcessJobNetRequest::MessageType();
}
//---------------------------------------------------------------------
void BuilderRegistration::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderRegistration>()
->Version(1)
->Field("Name", &BuilderRegistration::m_name)
->Field("Patterns", &BuilderRegistration::m_patterns)
->Field("BusId", &BuilderRegistration::m_busId)
->Field("Version", &BuilderRegistration::m_version)
->Field("AnalysisFingerprint", &BuilderRegistration::m_analysisFingerprint)
->Field("Flags", &BuilderRegistration::m_flags)
->Field("FlagsByJobKey", &BuilderRegistration::m_flagsByJobKey)
->Field("ProductsToKeepOnFailure", &BuilderRegistration::m_productsToKeepOnFailure);
}
}
void BuilderRegistrationRequest::Reflect(AZ::ReflectContext* context)
{
BuilderRegistration::Reflect(context);
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderRegistrationRequest, BaseAssetProcessorMessage>()->Version(1)->Field(
"Builders", &BuilderRegistrationRequest::m_builders);
}
}
unsigned int BuilderRegistrationRequest::GetMessageType() const
{
return BuilderRegistrationRequest::MessageType;
}
} // namespace AssetBuilder
@@ -0,0 +1,140 @@
/*
* 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 <AzFramework/Asset/AssetProcessorMessages.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
namespace AssetBuilder
{
void Reflect(AZ::ReflectContext* context);
void InitializeSerializationContext();
//! BuilderHelloRequest is sent by an AssetBuilder that is attempting to connect to the AssetProcessor to register itself as a worker
class BuilderHelloRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(BuilderHelloRequest, AZ::OSAllocator, 0);
AZ_RTTI(BuilderHelloRequest, "{5fab5962-a1d8-42a5-bf7a-fb1a8c5a9588}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
//! Unique ID assigned to this builder to identify it
AZ::Uuid m_uuid = AZ::Uuid::CreateNull();
};
//! BuilderHelloResponse contains the AssetProcessor's response to a builder connection attempt, indicating if it is accepted and the ID
//! that it was assigned
class BuilderHelloResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(BuilderHelloResponse, AZ::OSAllocator, 0);
AZ_RTTI(BuilderHelloResponse, "{5f3d7c11-6639-4c6f-980a-32be546903c2}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
//! Indicates if the builder was accepted by the AP
bool m_accepted = false;
//! Unique ID assigned to the builder. If the builder isn't a local process, this is the ID assigned by the AP
AZ::Uuid m_uuid = AZ::Uuid::CreateNull();
};
class CreateJobsNetRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(CreateJobsNetRequest, AZ::OSAllocator, 0);
AZ_RTTI(CreateJobsNetRequest, "{97fa717d-3a09-4d21-95c6-b2eafd773f1c}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
AssetBuilderSDK::CreateJobsRequest m_request;
};
class CreateJobsNetResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(CreateJobsNetResponse, AZ::OSAllocator, 0);
AZ_RTTI(CreateJobsNetResponse, "{b2c7c2d3-b60e-4b27-b699-43e0ba991c33}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
AssetBuilderSDK::CreateJobsResponse m_response;
};
class ProcessJobNetRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(ProcessJobNetRequest, AZ::OSAllocator, 0);
AZ_RTTI(ProcessJobNetRequest, "{05288de1-020b-48db-b9de-715f17284efa}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
AssetBuilderSDK::ProcessJobRequest m_request;
};
class ProcessJobNetResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(ProcessJobNetResponse, AZ::OSAllocator, 0);
AZ_RTTI(ProcessJobNetResponse, "{26ddf882-246c-4cfb-912f-9b8e389df4f6}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
AssetBuilderSDK::ProcessJobResponse m_response;
};
//////////////////////////////////////////////////////////////////////////
struct BuilderRegistration
{
AZ_CLASS_ALLOCATOR(BuilderRegistration, AZ::OSAllocator, 0);
AZ_TYPE_INFO(BuilderRegistration, "{36E785C3-5046-4568-870A-336C8249E453}");
static void Reflect(AZ::ReflectContext* context);
AZStd::string m_name;
AZStd::vector<AssetBuilderSDK::AssetBuilderPattern> m_patterns;
AZ::Uuid m_busId;
int m_version = 0;
AZStd::string m_analysisFingerprint;
AZ::u8 m_flags = 0;
AZStd::unordered_map<AZStd::string, AZ::u8> m_flagsByJobKey;
AZStd::unordered_map<AZStd::string, AZStd::unordered_set<AZ::u32>> m_productsToKeepOnFailure;
};
class BuilderRegistrationRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(BuilderRegistrationRequest, AZ::OSAllocator, 0);
AZ_RTTI(BuilderRegistrationRequest, "{FA9CF2D5-C847-47F3-979D-6C3AE061715C}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static constexpr unsigned int MessageType = AZ_CRC_CE("AssetSystem::BuilderRegistrationRequest");
BuilderRegistrationRequest() = default;
unsigned int GetMessageType() const override;
AZStd::vector<BuilderRegistration> m_builders;
};
} // namespace AssetBuilder
@@ -6,6 +6,22 @@
#
#
ly_add_target(
NAME AssetBuilder.Static STATIC
NAMESPACE AZ
FILES_CMAKE
asset_builder_static_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
.
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzFramework
AZ::AzToolsFramework
AZ::AssetBuilderSDK
)
ly_add_target(
NAME AssetBuilder EXECUTABLE
NAMESPACE AZ
@@ -17,6 +33,7 @@ ly_add_target(
.
BUILD_DEPENDENCIES
PRIVATE
AssetBuilder.Static
3rdParty::Qt::Core
3rdParty::Qt::Gui
3rdParty::Qt::Network
@@ -0,0 +1,12 @@
#
# 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(FILES
AssetBuilderStatic.h
AssetBuilderStatic.cpp
)
@@ -1172,19 +1172,10 @@ namespace AssetBuilderSDK
JobProduct::Reflect(context);
AssetBuilderDesc::Reflect(context);
RegisterBuilderRequest::Reflect(context);
RegisterBuilderResponse::Reflect(context);
CreateJobsRequest::Reflect(context);
CreateJobsResponse::Reflect(context);
ProcessJobRequest::Reflect(context);
ProcessJobResponse::Reflect(context);
BuilderHelloRequest::Reflect(context);
BuilderHelloResponse::Reflect(context);
CreateJobsNetRequest::Reflect(context);
CreateJobsNetResponse::Reflect(context);
ProcessJobNetRequest::Reflect(context);
ProcessJobNetResponse::Reflect(context);
}
void InitializeSerializationContext()
@@ -1263,24 +1254,6 @@ namespace AssetBuilderSDK
}
}
void RegisterBuilderRequest::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RegisterBuilderRequest>()->
Version(1)->
Field("FilePath", &RegisterBuilderRequest::m_filePath);
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<RegisterBuilderRequest>("RegisterBuilderRequest")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
->Property("filePath", BehaviorValueProperty(&RegisterBuilderRequest::m_filePath));
}
}
void AssetBuilderDesc::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
@@ -1313,25 +1286,6 @@ namespace AssetBuilderSDK
}
}
void RegisterBuilderResponse::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RegisterBuilderResponse>()
->Version(1)
->Field("Asset Builder Desc List", &RegisterBuilderResponse::m_assetBuilderDescList);
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<RegisterBuilderResponse>("RegisterBuilderResponse")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
->Constructor()
->Property("assetBuilderDescList", BehaviorValueProperty(&RegisterBuilderResponse::m_assetBuilderDescList));
}
}
bool CreateJobsResponse::Succeeded() const
{
return m_result == CreateJobsResultCode::Success;
@@ -1362,128 +1316,6 @@ namespace AssetBuilderSDK
}
}
void BuilderHelloRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderHelloRequest>()
->Version(1)
->Field("UUID", &BuilderHelloRequest::m_uuid);
}
}
unsigned int BuilderHelloRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::BuilderHelloRequest", 0x213a7248);
return messageType;
}
unsigned int BuilderHelloRequest::GetMessageType() const
{
return MessageType();
}
void BuilderHelloResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<BuilderHelloResponse>()
->Version(1)
->Field("Accepted", &BuilderHelloResponse::m_accepted)
->Field("UUID", &BuilderHelloResponse::m_uuid);
}
}
unsigned int BuilderHelloResponse::GetMessageType() const
{
return BuilderHelloRequest::MessageType();
}
//////////////////////////////////////////////////////////////////////////
void CreateJobsNetRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<CreateJobsNetRequest>()
->Version(1)
->Field("Request", &CreateJobsNetRequest::m_request);
}
}
unsigned int CreateJobsNetRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::CreateJobsNetRequest", 0xc48209c0);
return messageType;
}
unsigned int CreateJobsNetRequest::GetMessageType() const
{
return MessageType();
}
void CreateJobsNetResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<CreateJobsNetResponse>()
->Version(1)
->Field("Response", &CreateJobsNetResponse::m_response);
}
}
unsigned int CreateJobsNetResponse::GetMessageType() const
{
return CreateJobsNetRequest::MessageType();
}
void ProcessJobNetRequest::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<ProcessJobNetRequest>()
->Version(1)
->Field("Request", &ProcessJobNetRequest::m_request);
}
}
unsigned int ProcessJobNetRequest::MessageType()
{
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::ProcessJobNetRequest", 0x479f340f);
return messageType;
}
unsigned int ProcessJobNetRequest::GetMessageType() const
{
return MessageType();
}
void ProcessJobNetResponse::Reflect(AZ::ReflectContext* context)
{
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<ProcessJobNetResponse>()
->Version(1)
->Field("Response", &ProcessJobNetResponse::m_response);
}
}
unsigned int ProcessJobNetResponse::GetMessageType() const
{
return ProcessJobNetRequest::MessageType();
}
JobDependency::JobDependency(const AZStd::string& jobKey, const AZStd::string& platformIdentifier, const JobDependencyType& type, const SourceFileDependency& sourceFile)
: m_jobKey(jobKey)
, m_platformIdentifier(platformIdentifier)
@@ -464,35 +464,6 @@ namespace AssetBuilderSDK
AZStd::string m_platformIdentifier;
};
//! RegisterBuilderRequest contains input data that will be sent by the AssetProcessor to the builder during the startup registration phase
struct RegisterBuilderRequest
{
AZ_CLASS_ALLOCATOR(RegisterBuilderRequest, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(RegisterBuilderRequest, "{7C6C5198-4766-42B8-9A1E-48479CE2F5EA}");
AZStd::string m_filePath;
RegisterBuilderRequest() {}
explicit RegisterBuilderRequest(const AZStd::string& filePath)
: m_filePath(filePath)
{
}
static void Reflect(AZ::ReflectContext* context);
};
//! INTERNAL USE ONLY - RegisterBuilderResponse contains registration data that will be sent by the builder to the AssetProcessor in response to RegisterBuilderRequest
struct RegisterBuilderResponse
{
AZ_CLASS_ALLOCATOR(RegisterBuilderResponse, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(RegisterBuilderResponse, "{0AE5583F-C763-410E-BA7F-78BD90546C01}");
AZStd::vector<AssetBuilderDesc> m_assetBuilderDescList;
static void Reflect(AZ::ReflectContext* context);
};
/**
* This tells you about a platform in your CreateJobsRequest or your ProcessJobRequest
*/
@@ -756,99 +727,9 @@ namespace AssetBuilderSDK
static void Reflect(AZ::ReflectContext* context);
};
//! BuilderHelloRequest is sent by an AssetBuilder that is attempting to connect to the AssetProcessor to register itself as a worker
class BuilderHelloRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(BuilderHelloRequest, AZ::OSAllocator, 0);
AZ_RTTI(BuilderHelloRequest, "{5fab5962-a1d8-42a5-bf7a-fb1a8c5a9588}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
//! Unique ID assigned to this builder to identify it
AZ::Uuid m_uuid = AZ::Uuid::CreateNull();
};
//! BuilderHelloResponse contains the AssetProcessor's response to a builder connection attempt, indicating if it is accepted and the ID that it was assigned
class BuilderHelloResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(BuilderHelloResponse, AZ::OSAllocator, 0);
AZ_RTTI(BuilderHelloResponse, "{5f3d7c11-6639-4c6f-980a-32be546903c2}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
//! Indicates if the builder was accepted by the AP
bool m_accepted = false;
//! Unique ID assigned to the builder. If the builder isn't a local process, this is the ID assigned by the AP
AZ::Uuid m_uuid = AZ::Uuid::CreateNull();
};
class CreateJobsNetRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(CreateJobsNetRequest, AZ::OSAllocator, 0);
AZ_RTTI(CreateJobsNetRequest, "{97fa717d-3a09-4d21-95c6-b2eafd773f1c}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
CreateJobsRequest m_request;
};
class CreateJobsNetResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(CreateJobsNetResponse, AZ::OSAllocator, 0);
AZ_RTTI(CreateJobsNetResponse, "{b2c7c2d3-b60e-4b27-b699-43e0ba991c33}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
CreateJobsResponse m_response;
};
class ProcessJobNetRequest : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(ProcessJobNetRequest, AZ::OSAllocator, 0);
AZ_RTTI(ProcessJobNetRequest, "{05288de1-020b-48db-b9de-715f17284efa}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
static unsigned int MessageType();
unsigned int GetMessageType() const override;
ProcessJobRequest m_request;
};
class ProcessJobNetResponse : public AzFramework::AssetSystem::BaseAssetProcessorMessage
{
public:
AZ_CLASS_ALLOCATOR(ProcessJobNetResponse, AZ::OSAllocator, 0);
AZ_RTTI(ProcessJobNetResponse, "{26ddf882-246c-4cfb-912f-9b8e389df4f6}", BaseAssetProcessorMessage);
static void Reflect(AZ::ReflectContext* context);
unsigned int GetMessageType() const override;
ProcessJobResponse m_response;
};
//! JobCancelListener can be used by builders in their processJob method to listen for job cancellation request.
//! The address of this listener is the jobid which can be found in the process job request.
@@ -935,44 +816,3 @@ namespace AZ
AZ_TYPE_INFO_SPECIALIZE(AssetBuilderSDK::ProductPathDependencyType, "{EF77742B-9627-4072-B431-396AA7183C80}");
AZ_TYPE_INFO_SPECIALIZE(AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType, "{BE9C8805-DB17-4500-944A-EB33FD0BE347}");
}
//! This macro should be used by every AssetBuilder to register itself,
//! AssetProcessor uses these exported function to identify whether a dll is an Asset Builder or not
//! If you want something highly custom you can do these entry points yourself instead of using the macro.
#define REGISTER_ASSETBUILDER \
extern void BuilderOnInit(); \
extern void BuilderDestroy(); \
extern void BuilderRegisterDescriptors(); \
extern void BuilderAddComponents(AZ::Entity * entity); \
extern "C" \
{ \
AZ_DLL_EXPORT int IsAssetBuilder() \
{ \
return 0; \
} \
\
AZ_DLL_EXPORT void InitializeModule(AZ::EnvironmentInstance sharedEnvironment) \
{ \
AZ::Environment::Attach(sharedEnvironment); \
BuilderOnInit(); \
} \
\
AZ_DLL_EXPORT void UninitializeModule() \
{ \
BuilderDestroy(); \
AZ::Environment::Detach(); \
} \
\
AZ_DLL_EXPORT void ModuleRegisterDescriptors() \
{ \
BuilderRegisterDescriptors(); \
} \
\
AZ_DLL_EXPORT void ModuleAddComponents(AZ::Entity * entity) \
{ \
BuilderAddComponents(entity); \
} \
}
// confusion-reducing note: above end-brace is part of the macro, not a namespace
+10 -6
View File
@@ -42,6 +42,7 @@ ly_add_target(
AZ::AzQtComponents
AZ::AzToolsFramework
AZ::AssetBuilderSDK
AZ::AssetBuilder.Static
${additional_dependencies}
RUNTIME_DEPENDENCIES
AZ::AssetBuilder
@@ -52,7 +53,7 @@ get_property(asset_builders GLOBAL PROPERTY LY_ASSET_BUILDERS)
string (REPLACE ";" "," asset_builders "${asset_builders}")
ly_add_source_properties(
SOURCES native/utilities/ApplicationManager.cpp
PROPERTY COMPILE_DEFINITIONS
PROPERTY COMPILE_DEFINITIONS
VALUES LY_ASSET_BUILDERS="${asset_builders}"
)
@@ -147,9 +148,9 @@ endif()
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME AssetProcessor.Tests EXECUTABLE
NAME AssetProcessor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE AZ
AUTOMOC
AUTORCC
@@ -167,12 +168,12 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
)
ly_add_source_properties(
SOURCES native/tests/assetBuilderSDK/assetBuilderSDKTest.cpp
PROPERTY COMPILE_DEFINITIONS
PROPERTY COMPILE_DEFINITIONS
VALUES ${LY_PAL_TOOLS_DEFINES}
)
ly_add_source_properties(
SOURCES native/unittests/AssetProcessorManagerUnitTests.cpp
PROPERTY COMPILE_DEFINITIONS
PROPERTY COMPILE_DEFINITIONS
VALUES LY_CMAKE_BINARY_DIR="${CMAKE_BINARY_DIR}"
)
@@ -266,7 +267,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_googletest(
NAME AZ::AssetProcessor.Tests
TEST_COMMAND $<TARGET_FILE:AZ::AssetProcessor.Tests> --unittest --gtest_filter=-*.SUITE_sandbox*
)
ly_add_googlebenchmark(
NAME AZ::AssetProcessor.Benchmarks
TARGET AZ::AssetProcessor.Tests
)
endif()
@@ -63,13 +63,6 @@ set(FILES
native/resourcecompiler/RCJobSortFilterProxyModel.h
native/resourcecompiler/RCQueueSortModel.cpp
native/resourcecompiler/RCQueueSortModel.h
native/shadercompiler/shadercompilerjob.cpp
native/shadercompiler/shadercompilerjob.h
native/shadercompiler/shadercompilerManager.cpp
native/shadercompiler/shadercompilerManager.h
native/shadercompiler/shadercompilerMessages.h
native/shadercompiler/shadercompilerModel.cpp
native/shadercompiler/shadercompilerModel.h
native/utilities/ApplicationManagerAPI.h
native/utilities/ApplicationManager.cpp
native/utilities/ApplicationManager.h
@@ -67,8 +67,6 @@ set(FILES
native/unittests/PlatformConfigurationUnitTests.h
native/unittests/RCcontrollerUnitTests.cpp
native/unittests/RCcontrollerUnitTests.h
native/unittests/ShaderCompilerUnitTests.cpp
native/unittests/ShaderCompilerUnitTests.h
native/unittests/UnitTestRunner.cpp
native/unittests/UnitTestRunner.h
native/unittests/UtilitiesUnitTests.cpp
@@ -85,7 +85,7 @@ namespace AssetProcessor
enum AssetCatalogStatus
{
RequiresSaving,
RequiresSaving,
UpToDate
};
@@ -213,11 +213,11 @@ namespace AssetProcessor
bool m_critical = false;
int m_priority = -1;
// indicates whether we need to check the server first for the outputs of this job
// indicates whether we need to check the server first for the outputs of this job
// before we start processing locally
bool m_checkServer = false;
// Indicates whether this job needs to be processed irrespective of whether its fingerprint got modified or not.
// Indicates whether this job needs to be processed irrespective of whether its fingerprint got modified or not.
bool m_autoProcessJob = false;
AssetBuilderSDK::AssetBuilderDesc m_assetBuilderDesc;
@@ -251,9 +251,9 @@ namespace AssetProcessor
JobDetails() = default;
};
//! JobDesc struct is used for identifying jobs that need to be processed again
//! because of job dependency declared on them by other jobs
//! JobDesc struct is used for identifying jobs that need to be processed again
//! because of job dependency declared on them by other jobs
struct JobDesc
{
AZStd::string m_databaseSourceName;
@@ -283,7 +283,7 @@ namespace AssetProcessor
}
};
//! JobIndentifier is an internal structure that store all the data that can uniquely identify a job
//! JobIndentifier is an internal structure that store all the data that can uniquely identify a job
struct JobIndentifier
{
JobDesc m_jobDesc;
@@ -1,162 +0,0 @@
/*
* 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 "shadercompilerManager.h"
#include "shadercompilerjob.h"
#include <QThreadPool>
#include "native/utilities/assetUtils.h"
ShaderCompilerManager::ShaderCompilerManager(QObject* parent)
: QObject(parent)
, m_isUnitTesting(false)
, m_numberOfJobsStarted(0)
, m_numberOfJobsEnded(0)
, m_numberOfErrors(0)
{
}
ShaderCompilerManager::~ShaderCompilerManager()
{
}
void ShaderCompilerManager::process(unsigned int connID, unsigned int type, unsigned int serial, QByteArray payload)
{
(void)type;
(void)serial;
Q_ASSERT(AssetUtilities::ComputeCRC32Lowercase("ShaderCompilerProxyRequest") == type);
decodeShaderCompilerRequest(connID, payload);
}
void ShaderCompilerManager::decodeShaderCompilerRequest(unsigned int connID, QByteArray payload)
{
if (payload.length() < sizeof(unsigned int) + sizeof(unsigned int) + 2 + sizeof(unsigned short))
{
QString error = "Payload size is too small";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
return;
}
unsigned char* data_end = reinterpret_cast<unsigned char*>(payload.data() + payload.size());
unsigned int* requestId = reinterpret_cast<unsigned int*>(data_end - sizeof(unsigned int));
unsigned int* serverListSizePtr = reinterpret_cast<unsigned int*>(data_end - sizeof(unsigned int) - sizeof(unsigned int));
unsigned short* serverPortPtr = reinterpret_cast<unsigned short*>(data_end - sizeof(unsigned int) - sizeof(unsigned int) - sizeof(unsigned short));
ShaderCompilerRequestMessage msg;
QString error;
msg.requestId = *requestId;
msg.serverListSize = *serverListSizePtr;
msg.serverPort = *serverPortPtr;
if ((msg.serverListSize <= 0) || (msg.serverListSize > 100000))
{
error = "Shader Compiler Server List is wrong";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
return;
}
if (msg.serverPort == 0)
{
error = "Shader Compiler port is wrong";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
return;
}
char* position_of_first_null = reinterpret_cast<char*>(serverPortPtr) - 1;// -1 for null
if ((*position_of_first_null) != '\0')
{
error = "Shader Compiler payload is corrupt,position is not null";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
return;
}
char* beginning_of_serverList = position_of_first_null - msg.serverListSize;
char* position_of_second_null = beginning_of_serverList - 1;//-1 for null
if ((*position_of_second_null) != '\0')
{
error = "Shader Compiler payload is corrupt,position is not null";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
return;
}
unsigned int originalPayloadSize = static_cast<unsigned int>(payload.size()) - sizeof(unsigned int) - sizeof(unsigned int) - sizeof(unsigned short) - static_cast<unsigned int>(msg.serverListSize) - 2;
msg.serverList = beginning_of_serverList;
msg.originalPayload.insert(0, payload.data(), static_cast<unsigned int>(originalPayloadSize));
ShaderCompilerJob* shaderCompilerJob = new ShaderCompilerJob();
shaderCompilerJob->initialize(this, msg);
shaderCompilerJob->setIsUnitTesting(m_isUnitTesting);
m_shaderCompilerJobMap[msg.requestId] = connID;
shaderCompilerJob->setAutoDelete(true);
QThreadPool* threadPool = QThreadPool::globalInstance();
threadPool->start(shaderCompilerJob);
}
void ShaderCompilerManager::OnShaderCompilerJobComplete(QByteArray payload, unsigned int requestId)
{
auto iterator = m_shaderCompilerJobMap.find(requestId);
if (iterator != m_shaderCompilerJobMap.end())
{
sendResponse(iterator.value(), AssetUtilities::ComputeCRC32Lowercase("ShaderCompilerProxyResponse"), 0, payload);
}
else
{
QString error = "Shader Compiler cannot find the connection id";
AZ_Warning(AssetProcessor::ConsoleChannel, false, error.toUtf8().data());
emit sendErrorMessage(error);
}
}
void ShaderCompilerManager::sendResponse(unsigned int connId, unsigned int /*type*/, unsigned int /*serial*/, QByteArray payload)
{
EBUS_EVENT_ID(connId, AssetProcessor::ConnectionBus, SendRaw, AssetUtilities::ComputeCRC32Lowercase("ShaderCompilerProxyResponse"), 0, payload);
}
void ShaderCompilerManager::shaderCompilerError(QString errorMessage, QString server, QString timestamp, QString payload)
{
m_numberOfErrors++;
emit numberOfErrorsChanged();
emit sendErrorMessageFromShaderJob(errorMessage, server, timestamp, payload);
}
void ShaderCompilerManager::jobStarted()
{
m_numberOfJobsStarted++;
emit numberOfJobsStartedChanged();
}
void ShaderCompilerManager::jobEnded()
{
m_numberOfJobsEnded++;
numberOfJobsEndedChanged();
}
void ShaderCompilerManager::setIsUnitTesting(bool isUnitTesting)
{
m_isUnitTesting = isUnitTesting;
}
int ShaderCompilerManager::numberOfJobsStarted()
{
return m_numberOfJobsStarted;
}
int ShaderCompilerManager::numberOfJobsEnded()
{
return m_numberOfJobsEnded;
}
int ShaderCompilerManager::numberOfErrors()
{
return m_numberOfErrors;
}
@@ -1,67 +0,0 @@
/*
* 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
*
*/
#ifndef SHADERCOMPILERMANAGER_H
#define SHADERCOMPILERMANAGER_H
#if !defined(Q_MOC_RUN)
#include <QObject>
#include <QHash>
#include <QString>
#include <QByteArray>
#endif
typedef QHash<unsigned int, unsigned int> ShaderCompilerJobMap;
/**
* The Shader Compiler Manager class receive a shader compile request
* and starts a shader compiler job for it
*/
class ShaderCompilerManager
: public QObject
{
Q_OBJECT
Q_PROPERTY(int numberOfJobsStarted READ numberOfJobsStarted NOTIFY numberOfJobsStartedChanged)
Q_PROPERTY(int numberOfJobsEnded READ numberOfJobsEnded NOTIFY numberOfJobsEndedChanged)
Q_PROPERTY(int numberOfErrors READ numberOfErrors NOTIFY numberOfErrorsChanged)
public:
explicit ShaderCompilerManager(QObject* parent = 0);
virtual ~ShaderCompilerManager();
void process(unsigned int connID, unsigned int type, unsigned int serial, QByteArray payload);
void decodeShaderCompilerRequest(unsigned int connID, QByteArray payload);
void setIsUnitTesting(bool isUnitTesting);
int numberOfJobsStarted();
int numberOfJobsEnded();
int numberOfErrors();
virtual void sendResponse(unsigned int connId, unsigned int type, unsigned int serial, QByteArray payload);
signals:
void sendErrorMessage(QString errorMessage);
void sendErrorMessageFromShaderJob(QString errorMessage, QString server, QString timestamp, QString payload);
void numberOfJobsStartedChanged();
void numberOfJobsEndedChanged();
void numberOfErrorsChanged();
public slots:
void OnShaderCompilerJobComplete(QByteArray payload, unsigned int requestId);
void shaderCompilerError(QString errorMessage, QString server, QString timestamp, QString payload);
void jobStarted();
void jobEnded();
private:
ShaderCompilerJobMap m_shaderCompilerJobMap;
bool m_isUnitTesting;
int m_numberOfJobsStarted;
int m_numberOfJobsEnded;
int m_numberOfErrors;
};
#endif // SHADERCOMPILERMANAGER_H
@@ -1,24 +0,0 @@
/*
* 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
*
*/
#ifndef SHADERCOMPILERMESSAGES_H
#define SHADERCOMPILERMESSAGES_H
#include <QByteArray>
#include <QString>
struct ShaderCompilerRequestMessage
{
QByteArray originalPayload;
QString serverList;
unsigned short serverPort;
unsigned int serverListSize;
unsigned int requestId;
};
#endif //SHADERCOMPILERMESSAGES_H
@@ -1,150 +0,0 @@
/*
* 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 "shadercompilerModel.h"
namespace
{
ShaderCompilerModel* s_singleton = nullptr;
}
ShaderCompilerModel::ShaderCompilerModel(QObject* parent)
: QAbstractItemModel(parent)
{
Q_ASSERT(s_singleton == nullptr);
s_singleton = this;
}
ShaderCompilerModel::~ShaderCompilerModel()
{
s_singleton = nullptr;
}
ShaderCompilerModel* ShaderCompilerModel::Get()
{
return s_singleton;
}
QVariant ShaderCompilerModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
int row = index.row();
if (row < 0)
{
return QVariant();
}
if (row >= m_shaderErrorInfoList.count())
{
return QVariant();
}
switch (role)
{
case TimeStampRole:
return m_shaderErrorInfoList[row].m_shaderTimestamp;
case ServerRole:
return m_shaderErrorInfoList[row].m_shaderServerName;
case ErrorRole:
return m_shaderErrorInfoList[row].m_shaderError;
case OriginalRequestRole:
return m_shaderErrorInfoList[row].m_shaderOriginalPayload;
case Qt::DisplayRole:
switch (index.column())
{
case ColumnTimeStamp:
return m_shaderErrorInfoList[row].m_shaderTimestamp;
case ColumnServer:
return m_shaderErrorInfoList[row].m_shaderServerName;
case ColumnError:
return m_shaderErrorInfoList[row].m_shaderServerName;
}
}
return QVariant();
}
Qt::ItemFlags ShaderCompilerModel::flags(const QModelIndex& index) const
{
(void)index;
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
int ShaderCompilerModel::rowCount(const QModelIndex& parent) const
{
(void)parent;
return m_shaderErrorInfoList.count();
}
QModelIndex ShaderCompilerModel::parent(const QModelIndex&) const
{
return QModelIndex();
}
QModelIndex ShaderCompilerModel::index(int row, int column, const QModelIndex& parent) const
{
if (row >= rowCount(parent) || column >= columnCount(parent))
{
return QModelIndex();
}
return createIndex(row, column);
}
int ShaderCompilerModel::columnCount(const QModelIndex& parent) const
{
return parent.isValid() ? 0 : Column::Max;
}
QVariant ShaderCompilerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
switch (section)
{
case ColumnTimeStamp:
return tr("Time Stamp");
case ColumnServer:
return tr("Server");
case ColumnError:
return tr("Error");
default:
break;
}
}
return QAbstractItemModel::headerData(section, orientation, role);
}
QHash<int, QByteArray> ShaderCompilerModel::roleNames() const
{
QHash<int, QByteArray> result;
result[TimeStampRole] = "timestamp";
result[ServerRole] = "server";
result[ErrorRole] = "error";
result[OriginalRequestRole] = "originalRequest";
return result;
}
void ShaderCompilerModel::addShaderErrorInfoEntry(QString errorMessage, QString timestamp, QString payload, QString server)
{
ShaderCompilerErrorInfo shaderCompileErrorInfo(errorMessage, timestamp, payload, server);
beginInsertRows(QModelIndex(), m_shaderErrorInfoList.size(), m_shaderErrorInfoList.size());
m_shaderErrorInfoList.append(shaderCompileErrorInfo);
endInsertRows();
}
@@ -1,93 +0,0 @@
/*
* 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
*
*/
#ifndef SHADERCOMPILERMODEL_H
#define SHADERCOMPILERMODEL_H
#if !defined(Q_MOC_RUN)
#include <QAbstractItemModel>
#include <QList>
#include <QVariant>
#include <QHash>
#include <QByteArray>
#include <QString>
#endif
class QModelIndex;
class QObject;
struct ShaderCompilerErrorInfo
{
QString m_shaderError;
QString m_shaderTimestamp;
QString m_shaderOriginalPayload;
QString m_shaderServerName;
ShaderCompilerErrorInfo(QString shaderError, QString shaderTimestamp, QString shaderOriginalPayload, QString shaderServerName)
: m_shaderError(shaderError)
, m_shaderTimestamp(shaderTimestamp)
, m_shaderOriginalPayload(shaderOriginalPayload)
, m_shaderServerName(shaderServerName)
{
}
};
/** The Shader Compiler model is responsible for capturing error requests
*/
class ShaderCompilerModel
: public QAbstractItemModel
{
Q_OBJECT
public:
enum DataRoles
{
TimeStampRole = Qt::UserRole + 1,
ServerRole,
ErrorRole,
OriginalRequestRole,
};
enum Column
{
ColumnTimeStamp,
ColumnServer,
ColumnError,
Max
};
/// standard Qt constructor
explicit ShaderCompilerModel(QObject* parent = 0);
virtual ~ShaderCompilerModel();
// singleton pattern
static ShaderCompilerModel* Get();
/// QAbstractListModel interface
QModelIndex parent(const QModelIndex&) const override;
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
int columnCount(const QModelIndex&) const override;
virtual int rowCount(const QModelIndex& parent) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
virtual QVariant data(const QModelIndex& index, int role) const override;
virtual QHash<int, QByteArray> roleNames() const override;
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
public slots:
void addShaderErrorInfoEntry(QString errorMessage, QString timestamp, QString payload, QString server);
private:
QList<ShaderCompilerErrorInfo> m_shaderErrorInfoList;
};
#endif // SHADERCOMPILERMODEL_H
@@ -1,194 +0,0 @@
/*
* 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 "shadercompilerjob.h"
#include "native/assetprocessor.h"
#include <QTcpSocket>
ShaderCompilerJob::ShaderCompilerJob()
: m_isUnitTesting(false)
, m_manager(nullptr)
{
}
ShaderCompilerJob::~ShaderCompilerJob()
{
m_manager = nullptr;
}
ShaderCompilerRequestMessage ShaderCompilerJob::ShaderCompilerMessage() const
{
return m_ShaderCompilerMessage;
}
void ShaderCompilerJob::initialize(QObject* pManager, const ShaderCompilerRequestMessage& ShaderCompilerMessage)
{
m_manager = pManager;
m_ShaderCompilerMessage = ShaderCompilerMessage;
}
QString ShaderCompilerJob::getServerAddress()
{
if (isServerListEmpty())
{
return QString();
}
QString serverAddress;
if (!m_ShaderCompilerMessage.serverList.contains(","))
{
serverAddress = m_ShaderCompilerMessage.serverList;
m_ShaderCompilerMessage.serverList.clear();
return serverAddress;
}
QStringList serverList = m_ShaderCompilerMessage.serverList.split(",");
serverAddress = serverList.takeAt(0);
m_ShaderCompilerMessage.serverList = serverList.join(",");
return serverAddress;
}
bool ShaderCompilerJob::isServerListEmpty()
{
return m_ShaderCompilerMessage.serverList.isEmpty();
}
bool ShaderCompilerJob::attemptDelivery(QString serverAddress, QByteArray& payload)
{
QTcpSocket socket;
QString error;
int waitingTime = 8000; // 8 sec timeout for sending.
int jobCompileMaxTime = 1000 * 60; // 60 sec timeout for compilation
if (m_isUnitTesting)
{
waitingTime = 500;
jobCompileMaxTime = 500;
}
socket.connectToHost(serverAddress, m_ShaderCompilerMessage.serverPort, QIODevice::ReadWrite);
if (socket.waitForConnected(waitingTime))
{
qint64 bytesWritten = 0;
qint64 payloadSize = static_cast<qint64>(m_ShaderCompilerMessage.originalPayload.size());
// send payload size to server
while (bytesWritten != sizeof(qint64))
{
qint64 currentWrite = socket.write(reinterpret_cast<char*>(&payloadSize) + bytesWritten,
sizeof(qint64) - bytesWritten);
if (currentWrite == -1)
{
//It is important to note that we are only outputting the error to debugchannel only here because
//we are forwarding these error messages upstream to the manager,who will take the appropriate action
error = "Connection Lost:Unable to send data";
AZ_TracePrintf(AssetProcessor::DebugChannel, error.toUtf8().data());
QMetaObject::invokeMethod(m_manager, "shaderCompilerError", Qt::QueuedConnection, Q_ARG(QString, error), Q_ARG(QString, QDateTime::currentDateTime().toString()), Q_ARG(QString, QString(m_ShaderCompilerMessage.originalPayload)), Q_ARG(QString, serverAddress));
return false;
}
socket.flush();
bytesWritten += currentWrite;
}
bytesWritten = 0;
//send actual payload to server
while (bytesWritten != m_ShaderCompilerMessage.originalPayload.size())
{
qint64 currentWrite = socket.write(m_ShaderCompilerMessage.originalPayload.data() + bytesWritten,
m_ShaderCompilerMessage.originalPayload.size() - bytesWritten);
if (currentWrite == -1)
{
error = "Connection Lost:Unable to send data";
AZ_TracePrintf(AssetProcessor::DebugChannel, error.toUtf8().data());
QMetaObject::invokeMethod(m_manager, "shaderCompilerError", Qt::QueuedConnection, Q_ARG(QString, error), Q_ARG(QString, QDateTime::currentDateTime().toString()), Q_ARG(QString, QString(m_ShaderCompilerMessage.originalPayload)), Q_ARG(QString, serverAddress));
}
socket.flush();
bytesWritten += currentWrite;
}
}
else
{
error = "Unable to connect to IP Address " + serverAddress;
AZ_TracePrintf(AssetProcessor::DebugChannel, error.toUtf8().data());
QMetaObject::invokeMethod(m_manager, "shaderCompilerError", Qt::QueuedConnection, Q_ARG(QString, error), Q_ARG(QString, QDateTime::currentDateTime().toString()), Q_ARG(QString, QString(m_ShaderCompilerMessage.originalPayload)), Q_ARG(QString, serverAddress));
return false;
}
unsigned int expectedBytes = sizeof(unsigned int) + sizeof(qint8);
unsigned int bytesReadTotal = 0;
unsigned int messageSize = 0;
bool isMessageSizeKnown = false;
//read the entire payload
while ((bytesReadTotal < expectedBytes + messageSize))
{
if (socket.bytesAvailable() == 0)
{
if (!socket.waitForReadyRead(jobCompileMaxTime))
{
error = "Remote IP is taking too long to respond: " + serverAddress;
AZ_TracePrintf(AssetProcessor::DebugChannel, error.toUtf8().data());
QMetaObject::invokeMethod(m_manager, "shaderCompilerError", Qt::QueuedConnection, Q_ARG(QString, error), Q_ARG(QString, QDateTime::currentDateTime().toString()), Q_ARG(QString, QString(m_ShaderCompilerMessage.originalPayload)), Q_ARG(QString, serverAddress));
payload.clear();
return false;
}
}
qint64 bytesAvailable = socket.bytesAvailable();
if (bytesAvailable >= expectedBytes && !isMessageSizeKnown)
{
socket.peek(reinterpret_cast<char*>(&messageSize), sizeof(unsigned int));
payload.resize(expectedBytes + messageSize);
isMessageSizeKnown = true;
}
if (bytesAvailable > 0)
{
qint64 bytesRead = socket.read(payload.data() + bytesReadTotal, bytesAvailable);
if (bytesRead <= 0)
{
error = "Connection closed by remote IP Address " + serverAddress;
AZ_TracePrintf(AssetProcessor::DebugChannel, error.toUtf8().data());
QMetaObject::invokeMethod(m_manager, "shaderCompilerError", Qt::QueuedConnection, Q_ARG(QString, error), Q_ARG(QString, QDateTime::currentDateTime().toString()), Q_ARG(QString, QString(m_ShaderCompilerMessage.originalPayload)), Q_ARG(QString, serverAddress));
payload.clear();
return false;
}
bytesReadTotal = aznumeric_cast<uint32_t>(bytesReadTotal + bytesRead);
}
}
return true; // payload successfully send
}
void ShaderCompilerJob::run()
{
QMetaObject::invokeMethod(m_manager, "jobStarted", Qt::QueuedConnection);
QByteArray payload;
//until server list is empty, keep trying
while (!isServerListEmpty())
{
QString serverAddress = getServerAddress();
//attempt to send payload
if (attemptDelivery(serverAddress, payload))
{
break;
}
}
//we are appending request id at the end of every payload,
//therefore in the case of any errors also
//we will be sending atleast four bytes to the game
payload.append(reinterpret_cast<char*>(&m_ShaderCompilerMessage.requestId), sizeof(unsigned int));
QMetaObject::invokeMethod(m_manager, "OnShaderCompilerJobComplete", Qt::QueuedConnection, Q_ARG(QByteArray, payload), Q_ARG(unsigned int, m_ShaderCompilerMessage.requestId));
QMetaObject::invokeMethod(m_manager, "jobEnded", Qt::QueuedConnection);
}
void ShaderCompilerJob::setIsUnitTesting(bool isUnitTesting)
{
m_isUnitTesting = isUnitTesting;
}
@@ -1,44 +0,0 @@
/*
* 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
*
*/
#ifndef SHADERCOMPILERJOB_H
#define SHADERCOMPILERJOB_H
#include <QRunnable>
#include "shadercompilerMessages.h"
class QByteArray;
class QObject;
/**
* This class is responsible for connecting to the shader compiler server
* and getting back the response to the shader compiler manager
*/
class ShaderCompilerJob
: public QRunnable
{
public:
explicit ShaderCompilerJob();
virtual ~ShaderCompilerJob();
ShaderCompilerRequestMessage ShaderCompilerMessage() const;
void initialize(QObject* pManager, const ShaderCompilerRequestMessage& ShaderCompilerMessage);
QString getServerAddress();
bool isServerListEmpty();
virtual void run() override;
void setIsUnitTesting(bool isUnitTesting);
bool attemptDelivery(QString serverAddress, QByteArray& payload);
private:
ShaderCompilerRequestMessage m_ShaderCompilerMessage;
QObject* m_manager;
bool m_isUnitTesting;
};
#endif // SHADERCOMPILERJOB_H
@@ -18,8 +18,6 @@
#include <QCoreApplication>
AZ_UNIT_TEST_HOOK(new BaseAssetProcessorTestEnvironment)
namespace AssetProcessor
{
class UnitTestAppManager : public BatchApplicationManager
@@ -35,7 +33,7 @@ namespace AssetProcessor
{
return false;
}
// tests which use the builder bus plug in their own mock version, so disconnect ours.
AssetProcessor::AssetBuilderInfoBus::Handler::BusDisconnect();
@@ -59,7 +57,7 @@ namespace AssetProcessor
void SetUp() override
{
AssetProcessorTest::SetUp();
static int numParams = 1;
static char processName[] = {"AssetProcessorBatch"};
static char* namePtr = &processName[0];
@@ -147,7 +145,7 @@ namespace AssetProcessor
time.start();
actualTest->StartTest();
while (!testIsComplete)
{
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
@@ -5,76 +5,8 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "utilities/BatchApplicationManager.h"
#include <AzTest/AzTest.h>
#include <AzTest/Utils.h>
#include <native/tests/BaseAssetProcessorTest.h>
DECLARE_AZ_UNIT_TEST_MAIN()
int RunUnitTests(int argc, char* argv[], bool& ranUnitTests)
{
ranUnitTests = true;
INVOKE_AZ_UNIT_TEST_MAIN(nullptr); // nullptr turns off default test environment used to catch stray asserts
// This looks a bit weird, but the macro returns conditionally, so *if* we get here, it means the unit tests didn't run
ranUnitTests = false;
return 0;
}
int main(int argc, char* argv[])
{
qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "1");
AZ::Debug::Trace::HandleExceptions(true);
AZ::Test::ApplyGlobalParameters(&argc, argv);
// If "--unittest" is present on the command line, run unit testing
// and return immediately. Otherwise, continue as normal.
AZ::Test::addTestEnvironment(new BaseAssetProcessorTestEnvironment());
bool pauseOnComplete = false;
if (AZ::Test::ContainsParameter(argc, argv, "--pause-on-completion"))
{
pauseOnComplete = true;
}
bool ranUnitTests;
int result = RunUnitTests(argc, argv, ranUnitTests);
if (ranUnitTests)
{
if (pauseOnComplete)
{
system("pause");
}
return result;
}
BatchApplicationManager applicationManager(&argc, &argv);
setvbuf(stdout, NULL, _IONBF, 0); // Disabling output buffering to fix test failures due to incomplete logs
ApplicationManager::BeforeRunStatus status = applicationManager.BeforeRun();
if (status != ApplicationManager::BeforeRunStatus::Status_Success)
{
if (status == ApplicationManager::BeforeRunStatus::Status_Restarting)
{
//AssetProcessor will restart
return 0;
}
else
{
//Initialization failed
return 1;
}
}
return applicationManager.Run() ? 0 : 1;
}
AZ_UNIT_TEST_HOOK(new BaseAssetProcessorTestEnvironment)
@@ -29,14 +29,16 @@ namespace AssetProcessor
AssetTreeItem::AssetTreeItem(
AZStd::shared_ptr<AssetTreeItemData> data,
QIcon errorIcon,
QIcon folderIcon,
QIcon fileIcon,
AssetTreeItem* parentItem) :
m_data(data),
m_parent(parentItem),
m_errorIcon(errorIcon), // QIcon is implicitily shared.
m_folderIcon(QIcon(QStringLiteral(":/Gallery/Asset_Folder.svg"))),
m_fileIcon(QIcon(QStringLiteral(":/Gallery/Asset_File.svg")))
m_errorIcon(errorIcon), // QIcon is implicitly shared.
m_folderIcon(folderIcon),
m_fileIcon(fileIcon)
{
m_folderIcon.addFile(QStringLiteral(":/Gallery/Asset_Folder.svg"), QSize(), QIcon::Selected);
}
AssetTreeItem::~AssetTreeItem()
@@ -45,7 +47,7 @@ namespace AssetProcessor
AssetTreeItem* AssetTreeItem::CreateChild(AZStd::shared_ptr<AssetTreeItemData> data)
{
m_childItems.emplace_back(new AssetTreeItem(data, m_errorIcon, this));
m_childItems.emplace_back(new AssetTreeItem(data, m_errorIcon, m_folderIcon, m_fileIcon, this));
return m_childItems.back().get();
}
@@ -50,6 +50,8 @@ namespace AssetProcessor
explicit AssetTreeItem(
AZStd::shared_ptr<AssetTreeItemData> data,
QIcon errorIcon,
QIcon folderIcon,
QIcon fileIcon,
AssetTreeItem* parentItem = nullptr);
virtual ~AssetTreeItem();
@@ -16,9 +16,12 @@ namespace AssetProcessor
AssetTreeModel::AssetTreeModel(AZStd::shared_ptr<AzToolsFramework::AssetDatabase::AssetDatabaseConnection> sharedDbConnection, QObject *parent) :
QAbstractItemModel(parent),
m_sharedDbConnection(sharedDbConnection),
m_errorIcon(QStringLiteral(":/stylesheet/img/logging/error.svg"))
m_sharedDbConnection(sharedDbConnection)
, m_errorIcon(QStringLiteral(":/stylesheet/img/logging/error.svg"))
, m_folderIcon(QIcon(QStringLiteral(":/Gallery/Asset_Folder.svg")))
, m_fileIcon(QIcon(QStringLiteral(":/Gallery/Asset_File.svg")))
{
m_folderIcon.addFile(QStringLiteral(":/Gallery/Asset_Folder.svg"), QSize(), QIcon::Selected);
ApplicationManagerNotifications::Bus::Handler::BusConnect();
AzToolsFramework::AssetDatabase::AssetDatabaseNotificationBus::Handler::BusConnect();
}
@@ -40,7 +43,7 @@ namespace AssetProcessor
void AssetTreeModel::Reset()
{
beginResetModel();
m_root.reset(new AssetTreeItem(AZStd::make_shared<AssetTreeItemData>("", "", true, AZ::Uuid::CreateNull()), m_errorIcon));
m_root.reset(new AssetTreeItem(AZStd::make_shared<AssetTreeItemData>("", "", true, AZ::Uuid::CreateNull()), m_errorIcon, m_folderIcon, m_fileIcon));
ResetModel();
@@ -54,5 +54,7 @@ namespace AssetProcessor
AZStd::shared_ptr<AzToolsFramework::AssetDatabase::AssetDatabaseConnection> m_sharedDbConnection;
QIcon m_errorIcon;
QIcon m_folderIcon;
QIcon m_fileIcon;
};
}

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