merging latest development
Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
@@ -96,10 +96,6 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
|
||||
connect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::SetTableViewVisibleAfterFilter);
|
||||
|
||||
connect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::UpdateTableModelAfterFilter);
|
||||
connect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this,
|
||||
&AzAssetBrowserWindow::SelectionChangedSlot);
|
||||
@@ -251,24 +247,6 @@ void AzAssetBrowserWindow::SetExpandedAssetBrowserMode()
|
||||
|
||||
m_assetBrowserDisplayState = AzAssetBrowser::AssetBrowserDisplayState::ExpandedMode;
|
||||
|
||||
disconnect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::UpdateTableModelAfterFilter);
|
||||
disconnect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::SetTableViewVisibleAfterFilter);
|
||||
|
||||
disconnect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this,
|
||||
&AzAssetBrowserWindow::SelectionChangedSlot);
|
||||
disconnect(m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem);
|
||||
disconnect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearStringFilter, m_ui->m_searchWidget,
|
||||
&AzAssetBrowser::SearchWidget::ClearStringFilter);
|
||||
disconnect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearTypeFilter, m_ui->m_searchWidget,
|
||||
&AzAssetBrowser::SearchWidget::ClearTypeFilter);
|
||||
|
||||
if (m_ui->m_assetBrowserTableViewWidget->isVisible())
|
||||
{
|
||||
m_ui->m_assetBrowserTableViewWidget->setVisible(false);
|
||||
@@ -281,37 +259,9 @@ void AzAssetBrowserWindow::SetDefaultAssetBrowserMode()
|
||||
namespace AzAssetBrowser = AzToolsFramework::AssetBrowser;
|
||||
|
||||
m_assetBrowserDisplayState = AzAssetBrowser::AssetBrowserDisplayState::DefaultMode;
|
||||
|
||||
connect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::SetTableViewVisibleAfterFilter);
|
||||
|
||||
connect(
|
||||
m_filterModel.data(), &AzAssetBrowser::AssetBrowserFilterModel::filterChanged, this,
|
||||
&AzAssetBrowserWindow::UpdateTableModelAfterFilter);
|
||||
connect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::selectionChangedSignal, this,
|
||||
&AzAssetBrowserWindow::SelectionChangedSlot);
|
||||
connect(m_ui->m_assetBrowserTableViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem);
|
||||
connect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearStringFilter, m_ui->m_searchWidget,
|
||||
&AzAssetBrowser::SearchWidget::ClearStringFilter);
|
||||
connect(
|
||||
m_ui->m_assetBrowserTableViewWidget, &AzAssetBrowser::AssetBrowserTableView::ClearTypeFilter, m_ui->m_searchWidget,
|
||||
&AzAssetBrowser::SearchWidget::ClearTypeFilter);
|
||||
|
||||
//If the filter is not empty we want to switch views and Update the model
|
||||
UpdateTableModelAfterFilter();
|
||||
SetTableViewVisibleAfterFilter();
|
||||
}
|
||||
|
||||
void AzAssetBrowserWindow::UpdateTableModelAfterFilter()
|
||||
{
|
||||
if (!m_ui->m_searchWidget->GetFilterString().isEmpty())
|
||||
{
|
||||
m_tableModel->UpdateTableModelMaps();
|
||||
}
|
||||
}
|
||||
|
||||
void AzAssetBrowserWindow::SetTableViewVisibleAfterFilter()
|
||||
{
|
||||
@@ -389,8 +339,8 @@ void AzAssetBrowserWindow::SelectionChangedSlot(const QItemSelection& /*selected
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
// while its tempting to use Activated here, we dont actually want it to count as activation
|
||||
// just becuase on some OS clicking once is activation.
|
||||
// while its tempting to use Activated here, we don't actually want it to count as activation
|
||||
// just because on some OS clicking once is activation.
|
||||
void AzAssetBrowserWindow::DoubleClickedItem([[maybe_unused]] const QModelIndex& element)
|
||||
{
|
||||
namespace AzAssetBrowser = AzToolsFramework::AssetBrowser;
|
||||
|
||||
@@ -68,7 +68,6 @@ protected slots:
|
||||
void CreateSwitchViewMenu();
|
||||
void SetExpandedAssetBrowserMode();
|
||||
void SetDefaultAssetBrowserMode();
|
||||
void UpdateTableModelAfterFilter();
|
||||
void SetTableViewVisibleAfterFilter();
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
struct ICVar;
|
||||
|
||||
class CVarMenu
|
||||
: public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// CVar that can be toggled on and off
|
||||
struct CVarToggle
|
||||
|
||||
+87
-95
@@ -19,10 +19,9 @@ namespace Config
|
||||
|
||||
CConfigGroup::~CConfigGroup()
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
delete (*it);
|
||||
delete var;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,17 +30,15 @@ namespace Config
|
||||
m_vars.push_back(var);
|
||||
}
|
||||
|
||||
uint32 CConfigGroup::GetVarCount()
|
||||
AZ::u32 CConfigGroup::GetVarCount()
|
||||
{
|
||||
return static_cast<uint32>(m_vars.size());
|
||||
return aznumeric_cast<AZ::u32>(m_vars.size());
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(const char* szName)
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
@@ -53,20 +50,19 @@ namespace Config
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(const char* szName) const
|
||||
{
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(uint index)
|
||||
IConfigVar* CConfigGroup::GetVar(AZ::u32 index)
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
@@ -76,7 +72,7 @@ namespace Config
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(uint index) const
|
||||
const IConfigVar* CConfigGroup::GetVar(AZ::u32 index) const
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
@@ -89,114 +85,110 @@ namespace Config
|
||||
void CConfigGroup::SaveToXML(XmlNodeRef node)
|
||||
{
|
||||
// save only values that don't have default values
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave) || var->IsDefault())
|
||||
{
|
||||
if (!var->IsDefault())
|
||||
{
|
||||
const char* szName = var->GetName().c_str();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigGroup::LoadFromXML(XmlNodeRef node)
|
||||
{
|
||||
// save only values that don't have default values
|
||||
for (TConfigVariables::const_iterator it = m_vars.begin();
|
||||
it != m_vars.end(); ++it)
|
||||
// load values that are save-able
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
IConfigVar* var = (*it);
|
||||
if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
{
|
||||
const char* szName = var->GetName().c_str();
|
||||
continue;
|
||||
}
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
switch (var->GetType())
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
{
|
||||
currentValue = readValue.toUtf8().data();
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
currentValue = readValue.toUtf8().data();
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-69
@@ -8,8 +8,12 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
#define CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
struct ICVar;
|
||||
class XmlNodeRef;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
@@ -32,7 +36,7 @@ namespace Config
|
||||
eFlag_DoNotSave = 1 << 2,
|
||||
};
|
||||
|
||||
IConfigVar(const char* szName, const char* szDescription, EType varType, uint8 flags)
|
||||
IConfigVar(const char* szName, const char* szDescription, EType varType, AZ::u8 flags)
|
||||
: m_name(szName)
|
||||
, m_description(szDescription)
|
||||
, m_type(varType)
|
||||
@@ -42,22 +46,22 @@ namespace Config
|
||||
|
||||
virtual ~IConfigVar() = default;
|
||||
|
||||
ILINE EType GetType() const
|
||||
AZ_FORCE_INLINE EType GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ILINE const AZStd::string& GetName() const
|
||||
AZ_FORCE_INLINE const AZStd::string& GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
ILINE const AZStd::string& GetDescription() const
|
||||
AZ_FORCE_INLINE const AZStd::string& GetDescription() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
ILINE bool IsFlagSet(EFlags flag) const
|
||||
AZ_FORCE_INLINE bool IsFlagSet(EFlags flag) const
|
||||
{
|
||||
return 0 != (m_flags & flag);
|
||||
}
|
||||
@@ -68,73 +72,28 @@ namespace Config
|
||||
virtual void GetDefault(void* outPtr) const = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
static EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static EType TranslateType(const int&) { return eType_INT; }
|
||||
static EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
static constexpr EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static constexpr EType TranslateType(const int&) { return eType_INT; }
|
||||
static constexpr EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static constexpr EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
uint8 m_flags;
|
||||
AZ::u8 m_flags;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_description;
|
||||
void* m_ptr;
|
||||
ICVar* m_pCVar;
|
||||
};
|
||||
|
||||
// Typed wrapper for config variable
|
||||
template<class T>
|
||||
class TConfigVar
|
||||
: public IConfigVar
|
||||
{
|
||||
private:
|
||||
T m_default;
|
||||
|
||||
public:
|
||||
TConfigVar(const char* szName, const char* szDescription, uint8 flags, T& ptr, const T& defaultValue)
|
||||
: IConfigVar(szName, szDescription, IConfigVar::TranslateType(ptr), flags)
|
||||
, m_default(defaultValue)
|
||||
{
|
||||
m_ptr = &ptr;
|
||||
|
||||
// reset to default value on initializations
|
||||
ptr = defaultValue;
|
||||
}
|
||||
|
||||
virtual void Get(void* outPtr) const
|
||||
{
|
||||
*reinterpret_cast<T*>(outPtr) = *reinterpret_cast<const T*>(m_ptr);
|
||||
}
|
||||
|
||||
virtual void Set(const void* ptr)
|
||||
{
|
||||
*reinterpret_cast<T*>(m_ptr) = *reinterpret_cast<const T*>(ptr);
|
||||
}
|
||||
|
||||
virtual void Reset()
|
||||
{
|
||||
*reinterpret_cast<T*>(m_ptr) = m_default;
|
||||
}
|
||||
|
||||
virtual void GetDefault(void* outPtr) const
|
||||
{
|
||||
*reinterpret_cast<T*>(outPtr) = m_default;
|
||||
}
|
||||
|
||||
virtual bool IsDefault() const
|
||||
{
|
||||
return *reinterpret_cast<const T*>(m_ptr) == m_default;
|
||||
}
|
||||
};
|
||||
|
||||
// Group of configuration variables with optional mapping to CVars
|
||||
class CConfigGroup
|
||||
{
|
||||
private:
|
||||
typedef std::vector<IConfigVar*> TConfigVariables;
|
||||
using TConfigVariables = AZStd::vector<IConfigVar*> ;
|
||||
TConfigVariables m_vars;
|
||||
|
||||
typedef std::vector<ICVar*> TConsoleVariables;
|
||||
using TConsoleVariables = AZStd::vector<ICVar*>;
|
||||
TConsoleVariables m_consoleVars;
|
||||
|
||||
public:
|
||||
@@ -142,20 +101,13 @@ namespace Config
|
||||
virtual ~CConfigGroup();
|
||||
|
||||
void AddVar(IConfigVar* var);
|
||||
uint32 GetVarCount();
|
||||
AZ::u32 GetVarCount();
|
||||
IConfigVar* GetVar(const char* szName);
|
||||
IConfigVar* GetVar(uint index);
|
||||
IConfigVar* GetVar(AZ::u32 index);
|
||||
const IConfigVar* GetVar(const char* szName) const;
|
||||
const IConfigVar* GetVar(uint index) const;
|
||||
const IConfigVar* GetVar(AZ::u32 index) const;
|
||||
|
||||
void SaveToXML(XmlNodeRef node);
|
||||
void LoadFromXML(XmlNodeRef node);
|
||||
|
||||
template<class T>
|
||||
void AddVar(const char* szName, const char* szDescription, T& var, const T& defaultValue, uint8 flags = 0)
|
||||
{
|
||||
AddVar(new TConfigVar<T>(szName, szDescription, flags, var, defaultValue));
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_CONFIGGROUP_H
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
#define CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
@@ -53,6 +51,7 @@ private:
|
||||
|
||||
class UserPopupWidgetHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarUser, UserPropertyEditor>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(UserPopupWidgetHandler, AZ::SystemAllocator, 0);
|
||||
bool IsDefaultHandler() const override { return false; }
|
||||
@@ -67,6 +66,7 @@ public:
|
||||
|
||||
class FloatCurveHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarSpline, CSplineCtrl>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FloatCurveHandler, AZ::SystemAllocator, 0);
|
||||
bool IsDefaultHandler() const override { return false; }
|
||||
@@ -80,5 +80,3 @@ public:
|
||||
|
||||
void OnSplineChange(CSplineCtrl*);
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
|
||||
|
||||
@@ -58,17 +58,9 @@ private:
|
||||
void OnClicked() override
|
||||
{
|
||||
QString tempValue("");
|
||||
QString ext("");
|
||||
if (m_path.isEmpty() == false)
|
||||
if (!m_path.isEmpty() && !Path::GetExt(m_path).isEmpty())
|
||||
{
|
||||
if (Path::GetExt(m_path) == "")
|
||||
{
|
||||
tempValue = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
tempValue = m_path;
|
||||
}
|
||||
tempValue = m_path;
|
||||
}
|
||||
|
||||
AssetSelectionModel selection;
|
||||
|
||||
@@ -99,6 +99,7 @@ class FileResourceSelectorWidgetHandler
|
||||
: QObject
|
||||
, public AzToolsFramework::PropertyHandler < CReflectedVarResource, FileResourceSelectorWidget >
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FileResourceSelectorWidgetHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
|
||||
@@ -446,41 +446,54 @@ void ReflectedVarUserAdapter::SetVariable(IVariable *pVariable)
|
||||
m_reflectedVar.reset(new CReflectedVarUser( pVariable->GetHumanName().toUtf8().data()));
|
||||
}
|
||||
|
||||
void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
|
||||
void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable* pVariable)
|
||||
{
|
||||
QString value;
|
||||
pVariable->Get(value);
|
||||
m_reflectedVar->m_value = value.toUtf8().data();
|
||||
|
||||
//extract the list of custom items from the IVariable user data
|
||||
IVariable::IGetCustomItems* pGetCustomItems = static_cast<IVariable::IGetCustomItems*> (pVariable->GetUserData().value<void *>());
|
||||
if (pGetCustomItems != nullptr)
|
||||
{
|
||||
std::vector<IVariable::IGetCustomItems::SItem> items;
|
||||
QString dlgTitle;
|
||||
// call the user supplied callback to fill-in items and get dialog title
|
||||
bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
|
||||
if (bShowIt) // if func didn't veto, show the dialog
|
||||
{
|
||||
m_reflectedVar->m_enableEdit = true;
|
||||
m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
|
||||
m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
|
||||
m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
|
||||
m_reflectedVar->m_itemNames.resize(items.size());
|
||||
m_reflectedVar->m_itemDescriptions.resize(items.size());
|
||||
|
||||
QByteArray ba;
|
||||
int i = -1;
|
||||
std::generate(m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(), [&items, &i, &ba]() { ++i; ba = items[i].name.toUtf8(); return ba.data(); });
|
||||
i = -1;
|
||||
std::generate(m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(), [&items, &i, &ba]() { ++i; ba = items[i].desc.toUtf8(); return ba.data(); });
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
// extract the list of custom items from the IVariable user data
|
||||
IVariable::IGetCustomItems* pGetCustomItems = static_cast<IVariable::IGetCustomItems*>(pVariable->GetUserData().value<void*>());
|
||||
if (pGetCustomItems == nullptr)
|
||||
{
|
||||
m_reflectedVar->m_enableEdit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<IVariable::IGetCustomItems::SItem> items;
|
||||
QString dlgTitle;
|
||||
// call the user supplied callback to fill-in items and get dialog title
|
||||
bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
|
||||
if (!bShowIt) // if func vetoed it, don't show the dialog
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_reflectedVar->m_enableEdit = true;
|
||||
m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
|
||||
m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
|
||||
m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
|
||||
m_reflectedVar->m_itemNames.resize(items.size());
|
||||
m_reflectedVar->m_itemDescriptions.resize(items.size());
|
||||
|
||||
QByteArray ba;
|
||||
int i = -1;
|
||||
AZStd::generate(
|
||||
m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(),
|
||||
[&items, &i, &ba]()
|
||||
{
|
||||
++i;
|
||||
ba = items[i].name.toUtf8();
|
||||
return ba.data();
|
||||
});
|
||||
i = -1;
|
||||
AZStd::generate(
|
||||
m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(),
|
||||
[&items, &i, &ba]()
|
||||
{
|
||||
++i;
|
||||
ba = items[i].desc.toUtf8();
|
||||
return ba.data();
|
||||
});
|
||||
}
|
||||
|
||||
void ReflectedVarUserAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
|
||||
@@ -126,7 +126,6 @@ void TimelineWidget::DrawTicks(QPainter* painter)
|
||||
const QPen pOldPen = painter->pen();
|
||||
|
||||
const QPen ltgray(QColor(110, 110, 110));
|
||||
const QPen black(palette().color(QPalette::Normal, QPalette::Text));
|
||||
const QPen redpen(QColor(255, 0, 255));
|
||||
|
||||
// Draw time ticks every tick step seconds.
|
||||
@@ -598,7 +597,6 @@ void TimelineWidget::DrawSecondTicks(QPainter* painter)
|
||||
{
|
||||
const QPen ltgray(QColor(110, 110, 110));
|
||||
const QPen black(palette().color(QPalette::Normal, QPalette::Text));
|
||||
const QPen redpen(QColor(255, 0, 255));
|
||||
|
||||
for (int gx = m_grid.firstGridLine.x(); gx < m_grid.firstGridLine.x() + m_grid.numGridLines.x() + 1; gx++)
|
||||
{
|
||||
|
||||
@@ -832,7 +832,7 @@ QAction* LevelEditorMenuHandler::CreateViewPaneAction(const QtViewPane* view)
|
||||
|
||||
if (view->m_options.showOnToolsToolbar)
|
||||
{
|
||||
action->setIcon(QIcon(view->m_options.toolbarIcon));
|
||||
action->setIcon(QIcon(view->m_options.toolbarIcon.c_str()));
|
||||
}
|
||||
|
||||
m_actionManager->AddAction(view->m_id, action);
|
||||
|
||||
+15
-2
@@ -45,6 +45,7 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
@@ -547,7 +548,6 @@ public:
|
||||
{ "BatchMode", m_bConsoleMode },
|
||||
{ "NullRenderer", m_bNullRenderer },
|
||||
{ "devmode", m_bDeveloperMode },
|
||||
{ "VTUNE", dummy },
|
||||
{ "runpython", m_bRunPythonScript },
|
||||
{ "runpythontest", m_bRunPythonTestScript },
|
||||
{ "version", m_bShowVersionInfo },
|
||||
@@ -1686,6 +1686,11 @@ bool CCryEditApp::InitInstance()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get())
|
||||
{
|
||||
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "LegacySystemInterfaceCreated", R"({})");
|
||||
}
|
||||
|
||||
// Process some queued events come from system init
|
||||
// Such as asset catalog loaded notification.
|
||||
// There are some systems need to load configurations from assets for post initialization but before loading level
|
||||
@@ -4137,7 +4142,15 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
|
||||
AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware);
|
||||
Editor::EditorQtApplication* app = Editor::EditorQtApplication::newInstance(argc, argv);
|
||||
|
||||
if (app->arguments().contains("-autotest_mode"))
|
||||
QStringList qArgs = app->arguments();
|
||||
const bool is_automated_test = AZStd::any_of(qArgs.begin(), qArgs.end(),
|
||||
[](const QString& elem)
|
||||
{
|
||||
return elem.endsWith("autotest_mode") || elem.endsWith("runpythontest");
|
||||
}
|
||||
);
|
||||
|
||||
if (is_automated_test)
|
||||
{
|
||||
// Nullroute all stdout to null for automated tests, this way we make sure
|
||||
// that the test result output is not polluted with unrelated output data.
|
||||
|
||||
@@ -431,6 +431,7 @@ public:
|
||||
class CCrySingleDocTemplate
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
|
||||
: QObject()
|
||||
|
||||
@@ -60,15 +60,6 @@
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
#include <LmbrCentral/Rendering/EditorLightComponentBus.h> // for LmbrCentral::EditorLightComponentRequestBus
|
||||
|
||||
//#define PROFILE_LOADING_WITH_VTUNE
|
||||
|
||||
// profilers api.
|
||||
//#include "pure.h"
|
||||
#ifdef PROFILE_LOADING_WITH_VTUNE
|
||||
#include "C:\Program Files\Intel\Vtune\Analyzer\Include\VTuneApi.h"
|
||||
#pragma comment(lib,"C:\\Program Files\\Intel\\Vtune\\Analyzer\\Lib\\VTuneApi.lib")
|
||||
#endif
|
||||
|
||||
static const char* kAutoBackupFolder = "_autobackup";
|
||||
static const char* kHoldFolder = "$tmp_hold"; // conform to the ignored file types $tmp[0-9]*_ regex
|
||||
static const char* kSaveBackupFolder = "_savebackup";
|
||||
@@ -408,9 +399,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
|
||||
int t0 = GetTickCount();
|
||||
|
||||
#ifdef PROFILE_LOADING_WITH_VTUNE
|
||||
VTResume();
|
||||
#endif
|
||||
// Load level-specific audio data.
|
||||
AZStd::string levelFileName{ fileName.toUtf8().constData() };
|
||||
AZStd::to_lower(levelFileName.begin(), levelFileName.end());
|
||||
@@ -484,10 +472,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
|
||||
CSurfaceTypeValidator().Validate();
|
||||
|
||||
#ifdef PROFILE_LOADING_WITH_VTUNE
|
||||
VTPause();
|
||||
#endif
|
||||
|
||||
LogLoadTime(GetTickCount() - t0);
|
||||
// Loaded with success, remove event from log file
|
||||
GetIEditor()->GetSettingsManager()->UnregisterEvent(loadEvent);
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
// Notice : Refer to ViewportTitleDlg.cpp for a use case.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
#define CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
@@ -28,6 +26,7 @@ namespace Ui
|
||||
class CCustomResolutionDlg
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CCustomResolutionDlg(int w, int h, QWidget* pParent = nullptr);
|
||||
~CCustomResolutionDlg();
|
||||
@@ -42,5 +41,3 @@ protected:
|
||||
|
||||
QScopedPointer<Ui::CustomResolutionDlg> m_ui;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
|
||||
|
||||
@@ -211,9 +211,9 @@ public:
|
||||
|
||||
void Reset(QAction& action)
|
||||
{
|
||||
emit beginResetModel();
|
||||
beginResetModel();
|
||||
m_action = &action;
|
||||
emit endResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -266,7 +266,7 @@ QStringList CustomizeKeyboardDialog::BuildModels(QWidget* parent)
|
||||
categories.append(category);
|
||||
|
||||
QMenu* menu = menuAction->menu();
|
||||
m_menuActions[category] = GetAllActionsForMenu(menu, QStringLiteral(""));
|
||||
m_menuActions[category] = GetAllActionsForMenu(menu, QString());
|
||||
}
|
||||
|
||||
return categories;
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace SandboxEditor
|
||||
connect(m_ui->okButton, &QPushButton::clicked, this, &ErrorDialog::OnOK);
|
||||
connect(
|
||||
m_ui->messages,
|
||||
SIGNAL(itemSelectionChanged()),
|
||||
&QTreeWidget::itemSelectionChanged,
|
||||
this,
|
||||
SLOT(MessageSelectionChanged()));
|
||||
&ErrorDialog::MessageSelectionChanged);
|
||||
}
|
||||
|
||||
ErrorDialog::~ErrorDialog()
|
||||
|
||||
@@ -240,7 +240,7 @@ QJsonObject KeyboardCustomizationSettings::ExportGroup()
|
||||
|
||||
void KeyboardCustomizationSettings::ImportFromFile(QWidget* parent)
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QStringLiteral(""), QObject::tr("Keyboard Settings (*.keys)"));
|
||||
QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QString(), QObject::tr("Keyboard Settings (*.keys)"));
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace UnitTest
|
||||
|
||||
m_rootWidget = AZStd::make_unique<QWidget>();
|
||||
m_rootWidget->setFixedSize(QSize(100, 100));
|
||||
QApplication::setActiveWindow(m_rootWidget.get());
|
||||
|
||||
m_controllerList = AZStd::make_shared<AzFramework::ViewportControllerList>();
|
||||
m_controllerList->RegisterViewportContext(TestViewportId);
|
||||
@@ -100,6 +101,8 @@ namespace UnitTest
|
||||
m_controllerList.reset();
|
||||
m_rootWidget.reset();
|
||||
|
||||
QApplication::setActiveWindow(nullptr);
|
||||
|
||||
AllocatorsTestFixture::TearDown();
|
||||
}
|
||||
|
||||
@@ -110,7 +113,7 @@ namespace UnitTest
|
||||
|
||||
const AzFramework::ViewportId ViewportManipulatorControllerFixture::TestViewportId = AzFramework::ViewportId(0);
|
||||
|
||||
TEST_F(ViewportManipulatorControllerFixture, An_event_is_not_propagated_to_the_viewport_when_a_manipulator_handles_it_first)
|
||||
TEST_F(ViewportManipulatorControllerFixture, AnEventIsNotPropagatedToTheViewportWhenAManipulatorHandlesItFirst)
|
||||
{
|
||||
// forward input events to our controller list
|
||||
QObject::connect(
|
||||
@@ -151,4 +154,77 @@ namespace UnitTest
|
||||
|
||||
editorInteractionViewportFake.Disconnect();
|
||||
}
|
||||
|
||||
TEST_F(ViewportManipulatorControllerFixture, ChangingFocusDoesNotClearInput)
|
||||
{
|
||||
bool endedEvent = false;
|
||||
// detect input events and ensure that the Alt key press does not end before the end of the test
|
||||
QObject::connect(
|
||||
m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
|
||||
[&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
|
||||
{
|
||||
if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::ModifierAltL &&
|
||||
inputChannel->IsStateEnded())
|
||||
{
|
||||
endedEvent = true;
|
||||
}
|
||||
});
|
||||
|
||||
// given
|
||||
auto* secondaryWidget = new QWidget(m_rootWidget.get());
|
||||
|
||||
m_rootWidget->show();
|
||||
secondaryWidget->show();
|
||||
|
||||
m_rootWidget->setFocus();
|
||||
|
||||
// simulate a key press when root widget has focus
|
||||
QTest::keyPress(m_rootWidget.get(), Qt::Key_Alt, Qt::KeyboardModifier::AltModifier);
|
||||
|
||||
// when
|
||||
// change focus to secondary widget
|
||||
secondaryWidget->setFocus();
|
||||
|
||||
// then
|
||||
// the alt key was not released (cleared)
|
||||
EXPECT_FALSE(endedEvent);
|
||||
}
|
||||
|
||||
// note: Application State Change includes events such as switching to another application or minimizing
|
||||
// the current application
|
||||
TEST_F(ViewportManipulatorControllerFixture, ApplicationStateChangeDoesClearInput)
|
||||
{
|
||||
bool endedEvent = false;
|
||||
// detect input events and ensure that the Alt key press does not end before the end of the test
|
||||
QObject::connect(
|
||||
m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
|
||||
[&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
|
||||
{
|
||||
if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::AlphanumericW &&
|
||||
inputChannel->IsStateEnded())
|
||||
{
|
||||
endedEvent = true;
|
||||
}
|
||||
});
|
||||
|
||||
// given
|
||||
auto* secondaryWidget = new QWidget(m_rootWidget.get());
|
||||
|
||||
m_rootWidget->show();
|
||||
secondaryWidget->show();
|
||||
|
||||
m_rootWidget->setFocus();
|
||||
|
||||
// simulate a key press when root widget has focus
|
||||
QTest::keyPress(m_rootWidget.get(), Qt::Key_W);
|
||||
|
||||
// when
|
||||
// simulate changing the window state
|
||||
QApplicationStateChangeEvent applicationStateChangeEvent(Qt::ApplicationState::ApplicationInactive);
|
||||
QCoreApplication::sendEvent(m_rootWidget.get(), &applicationStateChangeEvent);
|
||||
|
||||
// then
|
||||
// the key was released (cleared)
|
||||
EXPECT_TRUE(endedEvent);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -419,7 +419,7 @@ void MemoryStatusItem::updateStatus()
|
||||
GeneralStatusItem::GeneralStatusItem(QString name, MainStatusBar* parent)
|
||||
: StatusBarItem(name, parent)
|
||||
{
|
||||
connect(parent, SIGNAL(messageChanged(QString)), this, SLOT(update()));
|
||||
connect(parent, &MainStatusBar::messageChanged, this, [this](const QString&) { update(); });
|
||||
}
|
||||
|
||||
QString GeneralStatusItem::CurrentText() const
|
||||
|
||||
@@ -100,9 +100,10 @@ CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
|
||||
m_level = "";
|
||||
// First of all, keyboard focus is related to widget tab order, and the default tab order is based on the order in which
|
||||
// widgets are constructed. Therefore, creating more widgets changes the keyboard focus. That is why setFocus() is called last.
|
||||
// Secondly, using singleShot() allows setFocus() slot of the QLineEdit instance to be invoked right after the event system
|
||||
// is ready to do so. Therefore, it is better to use singleShot() than directly call setFocus().
|
||||
QTimer::singleShot(0, ui->LEVEL, SLOT(OnStartup()));
|
||||
// in OnStartup()
|
||||
// Secondly, using singleShot() allows OnStartup() slot of the QLineEdit instance to be invoked right after the event system
|
||||
// is ready to do so. Therefore, it is better to use singleShot() than directly call OnStartup().
|
||||
QTimer::singleShot(0, this, &CNewLevelDialog::OnStartup);
|
||||
|
||||
ReloadLevelFolder();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#import <AppKit/NSEvent.h>
|
||||
|
||||
#include "EditorDefs.h"
|
||||
#include "QtEditorApplication.h"
|
||||
#include "QtEditorApplication_mac.h"
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <AzToolsFramework/Commands/EntityStateCommand.h>
|
||||
#include <AzToolsFramework/Commands/SelectionCommand.h>
|
||||
#include <AzToolsFramework/Commands/SliceDetachEntityCommand.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Editor/EditorContextMenuBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
@@ -642,6 +643,9 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
AzToolsFramework::EntityIdList selected;
|
||||
GetSelectedOrHighlightedEntities(selected);
|
||||
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
QAction* action = nullptr;
|
||||
|
||||
// when nothing is selected, entity is created at root level
|
||||
@@ -658,18 +662,20 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
// when a single entity is selected, entity is created as its child
|
||||
else if (selected.size() == 1)
|
||||
{
|
||||
action = menu->addAction(QObject::tr("Create entity"));
|
||||
QObject::connect(
|
||||
action, &QAction::triggered, action,
|
||||
[selected]
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, CreateNewEntityAsChild, selected.front());
|
||||
});
|
||||
auto containerEntityInterface = AZ::Interface<AzToolsFramework::ContainerEntityInterface>::Get();
|
||||
if (!prefabSystemEnabled || (containerEntityInterface && containerEntityInterface->IsContainerOpen(selected.front())))
|
||||
{
|
||||
action = menu->addAction(QObject::tr("Create entity"));
|
||||
QObject::connect(
|
||||
action, &QAction::triggered, action,
|
||||
[selected]
|
||||
{
|
||||
AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequestBus::Handler::CreateNewEntityAsChild, selected.front());
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!prefabSystemEnabled)
|
||||
{
|
||||
menu->addSeparator();
|
||||
@@ -1788,6 +1794,11 @@ AZStd::string SandboxIntegrationManager::GetComponentEditorIcon(const AZ::Uuid&
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
AZStd::string SandboxIntegrationManager::GetComponentTypeEditorIcon(const AZ::Uuid& componentType)
|
||||
{
|
||||
return GetComponentEditorIcon(componentType, nullptr);
|
||||
}
|
||||
|
||||
AZStd::string SandboxIntegrationManager::GetComponentIconPath(const AZ::Uuid& componentType,
|
||||
AZ::Crc32 componentIconAttrib, AZ::Component* component)
|
||||
{
|
||||
|
||||
@@ -233,6 +233,7 @@ private:
|
||||
}
|
||||
|
||||
AZStd::string GetComponentEditorIcon(const AZ::Uuid& componentType, AZ::Component* component) override;
|
||||
AZStd::string GetComponentTypeEditorIcon(const AZ::Uuid& componentType) override;
|
||||
AZStd::string GetComponentIconPath(const AZ::Uuid& componentType, AZ::Crc32 componentIconAttrib, AZ::Component* component) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -197,48 +197,46 @@ AssetCatalogModel::~AssetCatalogModel()
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZ::Data::AssetType AssetCatalogModel::GetAssetType(QString filename) const
|
||||
AZ::Data::AssetType AssetCatalogModel::GetAssetType(const QString &filename) const
|
||||
{
|
||||
AZ::Data::AssetType returnType = AZ::Uuid::CreateNull();
|
||||
|
||||
// Compare file extensions with the map created from the asset database.
|
||||
int dotIndex = filename.lastIndexOf('.');
|
||||
if (dotIndex >= 0)
|
||||
if (dotIndex < 0)
|
||||
{
|
||||
QString extension = filename.mid(dotIndex);
|
||||
for (auto pair : m_extensionToAssetType)
|
||||
{
|
||||
QString qExtensions = pair.first.c_str();
|
||||
if (qExtensions.indexOf(extension) >= 0)
|
||||
{
|
||||
if (pair.second.size() > 1)
|
||||
{
|
||||
// There are multiple types with this extension. Check each handler to see if they can handle this data type.
|
||||
AZStd::string azFilename = filename.toStdString().c_str();
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, MakePathAssetRootRelative, azFilename);
|
||||
AZ::Data::AssetId assetId;
|
||||
EBUS_EVENT_RESULT(assetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, azFilename.c_str(), AZ::Data::s_invalidAssetType, false);
|
||||
return AZ::Uuid::CreateNull();
|
||||
}
|
||||
|
||||
for (AZ::Uuid type : pair.second)
|
||||
{
|
||||
const AZ::Data::AssetHandler* handler = AZ::Data::AssetManager::Instance().GetHandler(type);
|
||||
if (handler && handler->CanHandleAsset(assetId))
|
||||
{
|
||||
returnType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnType = pair.second[0];
|
||||
break;
|
||||
}
|
||||
QStringRef extension = filename.midRef(dotIndex);
|
||||
for (const auto& pair : m_extensionToAssetType)
|
||||
{
|
||||
QString qExtensions = pair.first.c_str();
|
||||
if (qExtensions.indexOf(extension) < 0 || pair.second.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pair.second.size() == 1)
|
||||
{
|
||||
return pair.second[0];
|
||||
}
|
||||
|
||||
// There are multiple types with this extension. Search for a handler that can handle this data type.
|
||||
AZStd::string azFilename = filename.toStdString().c_str();
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, MakePathAssetRootRelative, azFilename);
|
||||
AZ::Data::AssetId assetId;
|
||||
EBUS_EVENT_RESULT(assetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, azFilename.c_str(), AZ::Data::s_invalidAssetType, false);
|
||||
|
||||
for (const AZ::Uuid& type : pair.second)
|
||||
{
|
||||
const AZ::Data::AssetHandler* handler = AZ::Data::AssetManager::Instance().GetHandler(type);
|
||||
if (handler && handler->CanHandleAsset(assetId))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnType;
|
||||
return AZ::Uuid::CreateNull();
|
||||
}
|
||||
|
||||
QStandardItem* AssetCatalogModel::GetPath(QString& path, bool createIfNeeded, QStandardItem* parent)
|
||||
@@ -419,7 +417,7 @@ AssetCatalogEntry* AssetCatalogModel::AddAsset(QString assetPath, AZ::Data::Asse
|
||||
// icons' memory being reclaimed and crashing the Editor.
|
||||
QSize size = fileIcon.actualSize(QSize(16, 16));
|
||||
QIcon deepCopy = fileIcon.pixmap(size).copy(0, 0, size.width(), size.height());
|
||||
|
||||
|
||||
if (!fileIcon.isNull())
|
||||
{
|
||||
m_assetTypeToIcon[assetType] = deepCopy;
|
||||
|
||||
@@ -110,7 +110,7 @@ protected:
|
||||
void SetFilterRegExp(const AZStd::string& filterType, const QRegExp& regExp);
|
||||
void ClearFilterRegExp(const AZStd::string& filterType = AZStd::string());
|
||||
|
||||
AZ::Data::AssetType GetAssetType(QString filename) const;
|
||||
AZ::Data::AssetType GetAssetType(const QString &filename) const;
|
||||
QStandardItem* GetPath(QString& path, bool createIfNeeded, QStandardItem* parent = nullptr);
|
||||
|
||||
void ApplyFilter(QStandardItem* parent);
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ ComponentDataModel::ComponentDataModel(QObject* parent)
|
||||
if (element.m_elementId == AZ::Edit::ClassElements::EditorData)
|
||||
{
|
||||
AZStd::string iconPath;
|
||||
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
m_componentIcons[classData->m_typeId] = QIcon(iconPath.c_str());
|
||||
|
||||
@@ -11,7 +11,6 @@ OutlinerWidget #m_display_options
|
||||
{
|
||||
qproperty-icon: url(:/Menu/menu.svg);
|
||||
qproperty-iconSize: 16px 16px;
|
||||
qproperty-flat: true;
|
||||
}
|
||||
|
||||
OutlinerWidget QWidget[PulseHighlight="true"]
|
||||
|
||||
@@ -408,7 +408,7 @@ CTrackViewNodesCtrl::CTrackViewNodesCtrl(QWidget* hParentWnd, CTrackViewDialog*
|
||||
serializeContext->EnumerateDerived<AZ::Component>([this](const AZ::SerializeContext::ClassData* classData, const AZ::Uuid&) -> bool
|
||||
{
|
||||
AZStd::string iconPath;
|
||||
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
m_componentTypeToIconMap[classData->m_typeId] = QIcon(iconPath.c_str());
|
||||
|
||||
@@ -65,8 +65,35 @@ namespace AZ
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides - Application is a singleton
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
typedef AZStd::recursive_mutex MutexType;
|
||||
static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
|
||||
static constexpr bool EnableEventQueue = true;
|
||||
using EventQueueMutexType = AZStd::mutex;
|
||||
struct PostThreadDispatchInvoker
|
||||
{
|
||||
~PostThreadDispatchInvoker();
|
||||
};
|
||||
|
||||
template <typename DispatchMutex>
|
||||
struct ThreadDispatchLockGuard
|
||||
{
|
||||
ThreadDispatchLockGuard(DispatchMutex& contextMutex)
|
||||
: m_lock{ contextMutex }
|
||||
{}
|
||||
ThreadDispatchLockGuard(DispatchMutex& contextMutex, AZStd::adopt_lock_t adopt_lock)
|
||||
: m_lock{ contextMutex, adopt_lock }
|
||||
{}
|
||||
ThreadDispatchLockGuard(const ThreadDispatchLockGuard&) = delete;
|
||||
ThreadDispatchLockGuard& operator=(const ThreadDispatchLockGuard&) = delete;
|
||||
private:
|
||||
PostThreadDispatchInvoker m_threadPolicyInvoker;
|
||||
using LockType = AZStd::conditional_t<LocklessDispatch, AZ::Internal::NullLockGuard<DispatchMutex>, AZStd::scoped_lock<DispatchMutex>>;
|
||||
LockType m_lock;
|
||||
};
|
||||
|
||||
template <typename DispatchMutex, bool>
|
||||
using DispatchLockGuard = ThreadDispatchLockGuard<DispatchMutex>;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~AssetCatalogRequests() = default;
|
||||
@@ -200,6 +227,17 @@ namespace AZ
|
||||
|
||||
using AssetCatalogRequestBus = AZ::EBus<AssetCatalogRequests>;
|
||||
|
||||
inline AssetCatalogRequests::PostThreadDispatchInvoker::~PostThreadDispatchInvoker()
|
||||
{
|
||||
if (!AssetCatalogRequestBus::IsInDispatchThisThread())
|
||||
{
|
||||
if (AssetCatalogRequestBus::QueuedEventCount())
|
||||
{
|
||||
AssetCatalogRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Events that AssetManager listens for
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzCore/Debug/LocalFileEventLogger.h>
|
||||
@@ -44,8 +45,6 @@
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <AzCore/Module/ModuleManager.h>
|
||||
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
#include <AzCore/Driller/Driller.h>
|
||||
@@ -216,11 +215,6 @@ namespace AZ
|
||||
m_oldProjectPath = newProjectPath;
|
||||
|
||||
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
|
||||
AZ::IO::FixedMaxPath projectMetadataFile{ AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath };
|
||||
projectMetadataFile /= "project.json";
|
||||
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
|
||||
// Update all the runtime file paths based on the new "project_path" value.
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
@@ -506,6 +500,16 @@ namespace AZ
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
|
||||
|
||||
// The /O3DE/Application/LifecycleEvents array contains a valid set of lifecycle events
|
||||
// Those lifecycle events are normally read from the <engine-root>/Registry
|
||||
// which isn't merged until ComponentApplication::Create invokes MergeSettingsToRegistry
|
||||
// So pre-populate the valid lifecycle even entries
|
||||
ComponentApplicationLifecycle::RegisterEvent(*m_settingsRegistry, "SystemAllocatorCreated");
|
||||
ComponentApplicationLifecycle::RegisterEvent(*m_settingsRegistry, "SettingsRegistryAvailable");
|
||||
ComponentApplicationLifecycle::RegisterEvent(*m_settingsRegistry, "ConsoleAvailable");
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "SystemAllocatorCreated", R"({})");
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "SettingsRegistryAvailable", R"({})");
|
||||
|
||||
// Create the Module Manager
|
||||
m_moduleManager = AZStd::make_unique<ModuleManager>();
|
||||
|
||||
@@ -520,6 +524,7 @@ namespace AZ
|
||||
m_ownsConsole = true;
|
||||
m_console->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
|
||||
m_settingsRegistryConsoleFunctors = AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_settingsRegistry, *m_console);
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "ConsoleAvailable", R"({})");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,6 +556,7 @@ namespace AZ
|
||||
{
|
||||
AZ::Interface<AZ::IConsole>::Unregister(m_console);
|
||||
delete m_console;
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "ConsoleUnavailable", R"({})");
|
||||
}
|
||||
|
||||
m_moduleManager.reset();
|
||||
@@ -558,6 +564,8 @@ namespace AZ
|
||||
if (AZ::SettingsRegistry::Get() == m_settingsRegistry.get())
|
||||
{
|
||||
SettingsRegistry::Unregister(m_settingsRegistry.get());
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "SettingsRegistryUnavailable", R"({})");
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "SystemAllocatorPendingDestruction", R"({})");
|
||||
}
|
||||
m_settingsRegistry.reset();
|
||||
|
||||
@@ -672,6 +680,8 @@ namespace AZ
|
||||
ReflectionEnvironment::GetReflectionManager()->Reflect(azrtti_typeid(this), [this](ReflectContext* context) {Reflect(context); });
|
||||
|
||||
RegisterCoreComponents();
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "ReflectionManagerAvailable", R"({})");
|
||||
|
||||
TickBus::AllowFunctionQueuing(true);
|
||||
SystemTickBus::AllowFunctionQueuing(true);
|
||||
|
||||
@@ -691,6 +701,7 @@ namespace AZ
|
||||
|
||||
// Load the actual modules
|
||||
LoadModules();
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "GemsLoaded", R"({})");
|
||||
|
||||
// Execute user.cfg after modules have been loaded but before processing any command-line overrides
|
||||
AZ::IO::FixedMaxPath platformCachePath;
|
||||
@@ -756,12 +767,14 @@ namespace AZ
|
||||
m_entities.rehash(0); // force free all memory
|
||||
|
||||
DestroyReflectionManager();
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "ReflectionManagerUnavailable", R"({})");
|
||||
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearNotifiers();
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearMergeEvents();
|
||||
|
||||
// Uninit and unload any dynamic modules.
|
||||
m_moduleManager->UnloadModules();
|
||||
ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "GemsUnloaded", R"({})");
|
||||
|
||||
NameDictionary::Destroy();
|
||||
|
||||
|
||||
@@ -175,6 +175,8 @@ namespace AZ
|
||||
bool m_loadDynamicModules = true;
|
||||
//! Used by test fixtures to ensure reflection occurs to edit context.
|
||||
bool m_createEditContext = false;
|
||||
//! Indicates whether the AssetCatalog.xml should be loaded by default in Application::StartCommon
|
||||
bool m_loadAssetCatalog = true;
|
||||
};
|
||||
|
||||
ComponentApplication();
|
||||
@@ -356,7 +358,7 @@ namespace AZ
|
||||
/// Calculates the root directory of the engine.
|
||||
void CalculateEngineRoot();
|
||||
|
||||
/// Calculates the directory where the bootstrap.cfg file resides.
|
||||
/// Deprecated: The term "AppRoot" has no meaning
|
||||
void CalculateAppRoot();
|
||||
|
||||
template<typename Iterator>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
|
||||
|
||||
namespace AZ::ComponentApplicationLifecycle
|
||||
{
|
||||
bool ValidateEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName)
|
||||
{
|
||||
using FixedValueString = SettingsRegistryInterface::FixedValueString;
|
||||
using Type = SettingsRegistryInterface::Type;
|
||||
FixedValueString eventRegistrationKey{ ApplicationLifecycleEventRegistrationKey };
|
||||
eventRegistrationKey += '/';
|
||||
eventRegistrationKey += eventName;
|
||||
return settingsRegistry.GetType(eventRegistrationKey) == Type::Object;
|
||||
}
|
||||
|
||||
bool SignalEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName, AZStd::string_view eventValue)
|
||||
{
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
using Format = AZ::SettingsRegistryInterface::Format;
|
||||
|
||||
if (!ValidateEvent(settingsRegistry, eventName))
|
||||
{
|
||||
AZ_Warning("ComponentApplicationLifecycle", false, R"(Cannot signal event %.*s. Name does is not a field of object "%.*s".)"
|
||||
R"( Please make sure the entry exists in the '<engine-root>/Registry/application_lifecycle_events.setreg")"
|
||||
" or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
|
||||
return false;
|
||||
}
|
||||
auto eventRegistrationKey = FixedValueString::format("%.*s/%.*s", AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey),
|
||||
AZ_STRING_ARG(eventName));
|
||||
|
||||
return settingsRegistry.MergeSettings(eventValue, Format::JsonMergePatch, eventRegistrationKey);
|
||||
}
|
||||
|
||||
bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName)
|
||||
{
|
||||
using FixedValueString = SettingsRegistryInterface::FixedValueString;
|
||||
using Format = AZ::SettingsRegistryInterface::Format;
|
||||
|
||||
if (!ValidateEvent(settingsRegistry, eventName))
|
||||
{
|
||||
FixedValueString eventRegistrationKey{ ApplicationLifecycleEventRegistrationKey };
|
||||
eventRegistrationKey += '/';
|
||||
eventRegistrationKey += eventName;
|
||||
return settingsRegistry.MergeSettings(R"({})", Format::JsonMergePatch, eventRegistrationKey);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RegisterHandler(AZ::SettingsRegistryInterface& settingsRegistry, AZ::SettingsRegistryInterface::NotifyEventHandler& handler,
|
||||
AZ::SettingsRegistryInterface::NotifyCallback callback, AZStd::string_view eventName, bool autoRegisterEvent)
|
||||
{
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
using Type = AZ::SettingsRegistryInterface::Type;
|
||||
using NotifyEventHandler = AZ::SettingsRegistryInterface::NotifyEventHandler;
|
||||
|
||||
// Some systems may attempt to register a handler before the settings registry has been loaded
|
||||
// If so, this flag lets them automatically register an event if it hasn't yet been registered.
|
||||
// RegisterEvent calls validate event.
|
||||
if ((!autoRegisterEvent && !ValidateEvent(settingsRegistry, eventName)) ||
|
||||
(autoRegisterEvent && !RegisterEvent(settingsRegistry, eventName)))
|
||||
{
|
||||
AZ_Warning(
|
||||
"ComponentApplicationLifecycle", false,
|
||||
R"(Cannot register event %.*s. Name is not a field of object "%.*s".)"
|
||||
R"( Please make sure the entry exists in the '<engine-root>/Registry/application_lifecycle_events.setreg")"
|
||||
" or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
|
||||
return false;
|
||||
}
|
||||
auto eventNameRegistrationKey = FixedValueString::format("%.*s/%.*s", AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey),
|
||||
AZ_STRING_ARG(eventName));
|
||||
auto lifecycleCallback = [callback = AZStd::move(callback), eventNameRegistrationKey](AZStd::string_view path, Type type)
|
||||
{
|
||||
if (path == eventNameRegistrationKey)
|
||||
{
|
||||
callback(path, type);
|
||||
}
|
||||
};
|
||||
|
||||
handler = NotifyEventHandler(AZStd::move(lifecycleCallback));
|
||||
settingsRegistry.RegisterNotifier(handler);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
namespace AZ::ComponentApplicationLifecycle
|
||||
{
|
||||
//! Root Key where lifecycle events should be registered under
|
||||
inline constexpr AZStd::string_view ApplicationLifecycleEventRegistrationKey = "/O3DE/Application/LifecycleEvents";
|
||||
|
||||
|
||||
//! Validates that the event @eventName is stored in the array at ApplicationLifecycleEventRegistrationKey
|
||||
//! @param settingsRegistry registry where @eventName will be searched
|
||||
//! @param eventName name of key that validated that exists as an element in the ApplicationLifecycleEventRegistrationKey array
|
||||
//! @return true if the @eventName was found in the ApplicationLifecycleEventRegistrationKey array
|
||||
bool ValidateEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
|
||||
|
||||
//! Wrapper around setting a value underneath the ApplicationLifecycleEventRegistrationKey
|
||||
//! It validates if the @eventName is is part of the ApplicationLifecycleEventRegistrationKey array
|
||||
//! It then appends the @eventName to the ApplicationLifecycleEventRegistrationKey merges the @eventValue into
|
||||
//! the SettingsRegistry at that key
|
||||
//! NOTE: This function should only be invoked from ComponentApplication and its derived classes
|
||||
//! @param settingsRegistry registry where eventName should be set
|
||||
//! @param eventName name of key underneath the ApplicationLifecycleEventRegistrationKey to signal
|
||||
//! @param eventValue JSON Object that will be merged into the SettingsRegistry at <ApplicationLifecycleEventRootKey>/<eventName>
|
||||
//! @return true if the eventValue was successfully merged at the <ApplicationLifecycleEventRootKey>/<eventName>
|
||||
bool SignalEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName, AZStd::string_view eventValue);
|
||||
|
||||
//! Register that the event @eventName is stored in the array at ApplicationLifecycleEventRegistrationKey
|
||||
//! @param settingsRegistry registry where @eventName will be searched
|
||||
//! @param eventName name of key that will be stored in the ApplicationLifecycleEventRegistrationKey array
|
||||
//! @return true if the event passed validation or the eventName was stored in the ApplicationLifecycleEventRegistrationKey array
|
||||
bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
|
||||
|
||||
//! Wrapper around registering the NotifyEventHandler with the SettingsRegistry for the specified event
|
||||
//! It validates if the @eventName is is part of the ApplicationLifecycleEventRegistrationKey array and if
|
||||
//! so moves the @callback into @handler and then registers the handler with the SettingsRegistry NotifyEvent
|
||||
//! @param settingsRegistry registry where handler will be registered
|
||||
//! @param handler handler where callback will be moved into and then registered with the SettingsRegistry
|
||||
//! if the specified @eventName passes validation
|
||||
//! @param callback will be moved into the handler if the specified @eventName is valid
|
||||
//! @param eventName name of key underneath the ApplicationLifecycleEventRegistrationKey to register
|
||||
//! @param autoRegisterEvent automatically register this event if it hasn't been registered yet. This is useful
|
||||
//! when registering a handler before the settings registry has been loaded.
|
||||
//! @return true if the handler was registered with the SettingsRegistry NotifyEvent
|
||||
bool RegisterHandler(AZ::SettingsRegistryInterface& settingsRegistry, AZ::SettingsRegistryInterface::NotifyEventHandler& handler,
|
||||
AZ::SettingsRegistryInterface::NotifyCallback callback, AZStd::string_view eventName, bool autoRegisterEvent = false);
|
||||
}
|
||||
@@ -168,6 +168,11 @@ namespace AZ
|
||||
|
||||
//! Rotation modifiers
|
||||
//! @{
|
||||
//! Set the world rotation matrix using the composition of rotations around
|
||||
//! the principle axes in the order of z-axis first and y-axis and then x-axis.
|
||||
//! @param eulerRadianAngles A Vector3 denoting radian angles of the rotations around each principle axis.
|
||||
virtual void SetWorldRotation([[maybe_unused]] const AZ::Vector3& eulerAnglesRadian) {}
|
||||
|
||||
//! Sets the entity's rotation in the world in quaternion notation.
|
||||
//! The origin of the axes is the entity's position in world space.
|
||||
//! @param quaternion A quaternion that represents the rotation to use for the entity.
|
||||
|
||||
@@ -262,6 +262,6 @@ static constexpr AZ::ThreadSafety ConsoleThreadSafety<_TYPE, std::enable_if_t<st
|
||||
//! @param _FLAGS a set of AzFramework::ConsoleFunctorFlags used to mutate behaviour
|
||||
//! @param _DESC a description of the cvar
|
||||
#define AZ_CONSOLEFREEFUNC_4(_NAME, _FUNCTION, _FLAGS, _DESC) \
|
||||
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(#_FUNCTION, _DESC, _FLAGS | AZ::ConsoleFunctorFlags::DontDuplicate, AZ::TypeId::CreateNull(), &_FUNCTION)
|
||||
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(_NAME, _DESC, _FLAGS | AZ::ConsoleFunctorFlags::DontDuplicate, AZ::TypeId::CreateNull(), &_FUNCTION)
|
||||
|
||||
#define AZ_CONSOLEFREEFUNC(...) AZ_MACRO_SPECIALIZE(AZ_CONSOLEFREEFUNC_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomVisitor.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
const char* VisitorError::CodeToString(VisitorErrorCode code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case VisitorErrorCode::UnsupportedOperation:
|
||||
return "operation not supported";
|
||||
case VisitorErrorCode::InvalidData:
|
||||
return "invalid data specified";
|
||||
case VisitorErrorCode::InternalError:
|
||||
return "internal error";
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
VisitorError::VisitorError(VisitorErrorCode code)
|
||||
: m_code(code)
|
||||
{
|
||||
}
|
||||
|
||||
VisitorError::VisitorError(VisitorErrorCode code, AZStd::string additionalInfo)
|
||||
: m_code(code)
|
||||
, m_additionalInfo(AZStd::move(additionalInfo))
|
||||
{
|
||||
}
|
||||
|
||||
VisitorErrorCode VisitorError::GetCode() const
|
||||
{
|
||||
return m_code;
|
||||
}
|
||||
|
||||
const AZStd::string& VisitorError::GetAdditionalInfo() const
|
||||
{
|
||||
return m_additionalInfo;
|
||||
}
|
||||
|
||||
AZStd::string VisitorError::FormatVisitorErrorMessage() const
|
||||
{
|
||||
if (m_additionalInfo.empty())
|
||||
{
|
||||
return AZStd::string::format("VisitorError: %s.", CodeToString(m_code));
|
||||
}
|
||||
return AZStd::string::format("VisitorError: %s. %s.", CodeToString(m_code), m_additionalInfo.c_str());
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorErrorCode code)
|
||||
{
|
||||
return AZ::Failure(VisitorError(code));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorErrorCode code, AZStd::string additionalInfo)
|
||||
{
|
||||
return AZ::Failure(VisitorError(code, AZStd::move(additionalInfo)));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorFailure(VisitorError error)
|
||||
{
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::VisitorSuccess()
|
||||
{
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Null()
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Bool([[maybe_unused]] bool value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Int64([[maybe_unused]] AZ::s64 value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Uint64([[maybe_unused]] AZ::u64 value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Double([[maybe_unused]] double value)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::String([[maybe_unused]] AZStd::string_view value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::OpaqueValue([[maybe_unused]] const OpaqueType& value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsOpaqueValues())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Opaque values are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawValue([[maybe_unused]] AZStd::string_view value, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsRawValues())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Raw values are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartObject()
|
||||
{
|
||||
if (!SupportsObjects())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Objects are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndObject([[maybe_unused]] AZ::u64 attributeCount)
|
||||
{
|
||||
if (!SupportsObjects())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Objects are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::Key([[maybe_unused]] AZ::Name key)
|
||||
{
|
||||
if (!SupportsObjects() && !SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Keys are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawKey(AZStd::string_view key, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
if (!SupportsRawKeys())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Raw keys are not supported by this visitor");
|
||||
}
|
||||
return Key(AZ::Name(key));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartArray()
|
||||
{
|
||||
if (!SupportsArrays())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Arrays are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndArray([[maybe_unused]] AZ::u64 elementCount)
|
||||
{
|
||||
if (!SupportsArrays())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Arrays are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::StartNode([[maybe_unused]] AZ::Name name)
|
||||
{
|
||||
if (!SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Nodes are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::RawStartNode(AZStd::string_view name, [[maybe_unused]] Lifetime lifetime)
|
||||
{
|
||||
return StartNode(AZ::Name(name));
|
||||
}
|
||||
|
||||
Visitor::Result Visitor::EndNode([[maybe_unused]] AZ::u64 attributeCount, [[maybe_unused]] AZ::u64 elementCount)
|
||||
{
|
||||
if (!SupportsNodes())
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::UnsupportedOperation, "Nodes are not supported by this visitor");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
VisitorFlags Visitor::GetVisitorFlags() const
|
||||
{
|
||||
// By default support raw keys (promoting them to AZ::Name) and support Array / Object / Node
|
||||
// We leave Opaque type support and Raw Values to more specialized, implementation-specific cases
|
||||
return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects | VisitorFlags::SupportsNodes;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsRawValues() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsRawValues) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsRawKeys() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsRawKeys) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsObjects() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsObjects) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsArrays() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsArrays) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsNodes() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsNodes) != VisitorFlags::Null;
|
||||
}
|
||||
|
||||
bool Visitor::SupportsOpaqueValues() const
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsOpaqueValues) != VisitorFlags::Null;
|
||||
}
|
||||
} // namespace AZ::DOM
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
//
|
||||
// Lifetime enum
|
||||
//
|
||||
//! Specifies the period in which a reference value will still be alive and safe to read.
|
||||
enum class Lifetime
|
||||
{
|
||||
//! Specifies that the value is safe to read and will remain so indefinitely.
|
||||
//! This implies that the value will not be mutated for the duration of this storage.
|
||||
Persistent,
|
||||
//! Specifies that the value may change or be deallocated, and must be copied to be safely stored.
|
||||
Temporary,
|
||||
};
|
||||
|
||||
//
|
||||
// VisitorErrorCode enum
|
||||
//
|
||||
//! Error code specifying the reason a Visitor operation failed.
|
||||
enum class VisitorErrorCode
|
||||
{
|
||||
//! Set when a Visitor doesn't have an implementation for a given attribute type.
|
||||
//! A pure-JSON serializer might reject a Node attribute, for example, and serialization visitors
|
||||
//! can forbid non-serializable Opaque types.
|
||||
UnsupportedOperation,
|
||||
//! Set when a Visitor has received malformed or invalid data.
|
||||
//! Potential sources include mismatching Begin/End call pairs or invalid attribute or element counts
|
||||
//! being sent to End methods.
|
||||
InvalidData,
|
||||
//! The Visitor failed for some other reason not caused by invalid input.
|
||||
//! If returning a custom error with this code, it's preferrable to also provide supplemental info
|
||||
//! in the form of an explanatory string.
|
||||
InternalError
|
||||
};
|
||||
|
||||
//
|
||||
// VisitorError class
|
||||
//
|
||||
//! Details of the reason for failure within a VisitorInterface operation.
|
||||
class VisitorError final
|
||||
{
|
||||
public:
|
||||
explicit VisitorError(VisitorErrorCode code);
|
||||
VisitorError(VisitorErrorCode code, AZStd::string additionalInfo);
|
||||
|
||||
//! Gets the error code associated with this error.
|
||||
VisitorErrorCode GetCode() const;
|
||||
//! Gets a supplemental error info string from the error.
|
||||
//! Returns an empty string if no additional information was provided to the error.
|
||||
const AZStd::string& GetAdditionalInfo() const;
|
||||
//! Provides a formatted, human-readable error description that can be used for logging purposes.
|
||||
AZStd::string FormatVisitorErrorMessage() const;
|
||||
|
||||
//! Helper method, translates a VisitorErrorCode to a human readable string.
|
||||
static const char* CodeToString(VisitorErrorCode code);
|
||||
|
||||
private:
|
||||
VisitorErrorCode m_code;
|
||||
AZStd::string m_additionalInfo;
|
||||
};
|
||||
|
||||
//! A type alias for opaque DOM types that aren't meant to be serializable.
|
||||
//! /see VisitorInterface::OpaqueValue
|
||||
using OpaqueType = AZStd::any;
|
||||
|
||||
//
|
||||
// VisitorFlags enum
|
||||
//
|
||||
//! Flags representning capabilities of a \ref Visitor.
|
||||
enum class VisitorFlags : AZ::u16
|
||||
{
|
||||
//! No flags are set. This can be used in conjunction with bitwise operators to check a flag.
|
||||
Null = 0,
|
||||
//! If set, this Visitor interface supports raw strings in place of specific value types.
|
||||
//! Visitors with this flag accept RawValue calls in lieu of more specific value calls such as Int64 or String.
|
||||
SupportsRawValues = (1 << 1),
|
||||
//! If set, this Visitor interface supports raw strings in place of Name types for keys and Node names.
|
||||
//! Visitors with this flag accept RawKey and RawStartNode in lieu of Key and StartNode calls.
|
||||
SupportsRawKeys = (1 << 2),
|
||||
//! If set, this Visitor interface supports Object types described via BeginObject and EndObject.
|
||||
SupportsObjects = (1 << 3),
|
||||
//! If set, this Visitor interface supports Array types described via BeginArray and EndArray.
|
||||
SupportsArrays = (1 << 4),
|
||||
//! If set, this Visitor interface supports Node types described BeginNode and EndNode.
|
||||
SupportsNodes = (1 << 4),
|
||||
//! If set, this Visitor interface supports opaque values described via OpaqueValue.
|
||||
SupportsOpaqueValues = (1 << 5),
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(VisitorFlags);
|
||||
|
||||
//
|
||||
// Visitor class
|
||||
//
|
||||
//! An interface for performing operations on elements of a generic DOM (Document Object Model).
|
||||
//! A Document Object Model is defined here as a tree structure comprised of one of the following values:
|
||||
//! - Primitives: plain data types, including
|
||||
//! - \ref Int64: 64 bit signed integer
|
||||
//! - \ref Uint64: 64 bit unsigned integer
|
||||
//! - \ref Bool: boolean value
|
||||
//! - \ref Double: 64 bit double precision float
|
||||
//! - \ref Null: sentinel "empty" type with no value representation
|
||||
//! - \ref String: UTF8 encoded string
|
||||
//! - \ref Object: an ordered container of key/value pairs where keys are AZ::Names and values may be any DOM type
|
||||
//! (including Object)
|
||||
//! - \ref Array: an ordered container of values, in which values are any DOM value type (including Array)
|
||||
//! - \ref Node: a container
|
||||
//! - \ref OpaqueValue: An arbitrary value stored in an AZStd::any. This is a non-serializable representation of an
|
||||
//! entry useful for in-memory options. This is intended to be used as an intermediate value over the course of DOM
|
||||
//! transformation and as a proxy to pass through types of which the DOM has no knowledge to other systems.
|
||||
//!
|
||||
//! Opaque values are rejected by the default VisitorInterface implementation.
|
||||
//!
|
||||
//! Care should be ensured that DOMs representing opaque types are only visited by consumers that understand them.
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() = default;
|
||||
|
||||
//! The result of a Visitor operation.
|
||||
//! A failure indicates a non-recoverable issue and signals that no further visit calls may be made in the
|
||||
//! current state.
|
||||
using Result = AZ::Outcome<void, VisitorError>;
|
||||
|
||||
//! Returns a set of flags representing the operations this Visitor supports.
|
||||
//! The base implementation supports raw keys (\see VisitorFlags::SupportsRawKeys) and
|
||||
//! arrays (\see VisitorFlags::SupportsArrays), objects (\see VisitorFlags::SupportsObjects), and
|
||||
//! nodes (\see VisitorFlags::SupportsNodes).
|
||||
//! Raw (\see VisitorFlags::SupportsRawValues) and opaque values (\see VisitorFlags::SupportsOpaqueValues)
|
||||
//! are disallowed by default, as their handling is intended to be implementation-specific.
|
||||
virtual VisitorFlags GetVisitorFlags() const;
|
||||
//! /see VisitorFlags::SupportsRawValues
|
||||
bool SupportsRawValues() const;
|
||||
//! /see VisitorFlags::SupportsRawKeys
|
||||
bool SupportsRawKeys() const;
|
||||
//! /see VisitorFlags::SupportsObjects
|
||||
bool SupportsObjects() const;
|
||||
//! /see VisitorFlags::SupportsArrays
|
||||
bool SupportsArrays() const;
|
||||
//! /see VisitorFlags::SupportsNodes
|
||||
bool SupportsNodes() const;
|
||||
//! /see VisitorFlags::SupportsOpaqueValues
|
||||
bool SupportsOpaqueValues() const;
|
||||
|
||||
//! Operates on an empty null value.
|
||||
virtual Result Null();
|
||||
//! Operates on a bool value.
|
||||
virtual Result Bool(bool value);
|
||||
//! Operates on a signed, 64 bit integer value.
|
||||
virtual Result Int64(AZ::s64 value);
|
||||
//! Operates on an unsigned, 64 bit integer value.
|
||||
virtual Result Uint64(AZ::u64 value);
|
||||
//! Operates on a double precision, 64 bit floating point value.
|
||||
virtual Result Double(double value);
|
||||
//! Operates on a string value. As strings are a reference type.
|
||||
//! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy.
|
||||
virtual Result String(AZStd::string_view value, Lifetime lifetime);
|
||||
//! Operates on an opaque value. As opaque values are a reference type, storage semantics are provided to
|
||||
//! indicate where the value may be stored persistently or requires a copy.
|
||||
//! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special
|
||||
//! cases with specific implementations, not generic usage.
|
||||
//! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy.
|
||||
virtual Result OpaqueValue(const OpaqueType& value, Lifetime lifetime);
|
||||
//! Operates on a raw value encoded as a UTF-8 string that hasn't had its type deduced.
|
||||
//! Visitors that support raw values (\see VisitorFlags::SupportsRawValues) may parse the raw value and
|
||||
//! forward it to the corresponding value call or calls of their choice.
|
||||
//! The base implementation of RawValue rejects the operation, as raw values are meant to be handled on
|
||||
//! a per-implementation basis.
|
||||
virtual Result RawValue(AZStd::string_view value, Lifetime lifetime);
|
||||
|
||||
//! Operates on an Object.
|
||||
//! Callers may make any number of Key calls, followed by calls representing a value (including a nested
|
||||
//! StartObject call) and then must call EndObject.
|
||||
virtual Result StartObject();
|
||||
//! Finishes operating on an Object.
|
||||
//! Callers must provide the number of attributes that were provided to the object, i.e. the number of key
|
||||
//! and value calls made within the direct context of this object (but not any nested objects / nodes).
|
||||
virtual Result EndObject(AZ::u64 attributeCount);
|
||||
|
||||
//! Specifies a key for a key/value pair.
|
||||
//! Key must be called subsequent to a call to \ref StartObject or \ref StartNode and immediately followed by
|
||||
//! calls representing the key's associated value.
|
||||
virtual Result Key(AZ::Name key);
|
||||
//! Specifies a key for a key/value pair using a raw string instead of \ref AZ::Name.
|
||||
//! \see Key
|
||||
virtual Result RawKey(AZStd::string_view key, Lifetime lifetime);
|
||||
|
||||
//! Operates on an Array.
|
||||
//! Callers may make any number of subsequent value calls to represent the elements of the array, and then must
|
||||
//! call EndArray.
|
||||
virtual Result StartArray();
|
||||
//! Finishes operating on an Array.
|
||||
//! Callers must provide the number of elements that were provided to the array, i.e. the number of value calls
|
||||
//! made within the direct context of this array (but not any nested arrays / nodes).
|
||||
virtual Result EndArray(AZ::u64 elementCount);
|
||||
|
||||
//! Operates on a Node.
|
||||
//! Callers may make any number of Key calls followed by value calls or value calls not prefixed with a Key
|
||||
//! call, and then must call EndNode. See \ref StartObject and \ref StartArray as Node types combine the
|
||||
//! functionality of both structures into a named Node structure.
|
||||
virtual Result StartNode(AZ::Name name);
|
||||
//! Operates on a Node using a raw string instead of \ref AZ::Name.
|
||||
//! \see StartNode
|
||||
virtual Result RawStartNode(AZStd::string_view name, Lifetime lifetime);
|
||||
//! Finishes operating on a Node.
|
||||
//! Callers must provide both the number of attributes the were provided and the number of elements that were
|
||||
//! provided to the node, attributes being values prefaced by a call to Key.
|
||||
virtual Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount);
|
||||
|
||||
protected:
|
||||
Visitor() = default;
|
||||
|
||||
//! Helper method, constructs a failure \ref Result with the specified code.
|
||||
static Result VisitorFailure(VisitorErrorCode code);
|
||||
//! Helper method, constructs a failure \ref Result with the specified code and supplemental info.
|
||||
static Result VisitorFailure(VisitorErrorCode code, AZStd::string additionalInfo);
|
||||
//! Helper method, constructs a failure \ref Result with the specified error.
|
||||
static Result VisitorFailure(VisitorError error);
|
||||
//! Helper method, constructs a success \ref Result.
|
||||
static Result VisitorSuccess();
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
@@ -7,4 +7,63 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Debug/ProfilerBus.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
AZStd::string GenerateOutputFile(const char* nameHint)
|
||||
{
|
||||
AZ::IO::FixedMaxPathString captureOutput = GetProfilerCaptureLocation();
|
||||
return AZStd::string::format("%s/capture_%s_%lld.json", captureOutput.c_str(), nameHint, AZStd::GetTimeNowSecond());
|
||||
}
|
||||
|
||||
void ProfilerCaptureFrame([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (auto profilerSystem = ProfilerSystemInterface::Get(); profilerSystem)
|
||||
{
|
||||
AZStd::string captureFile = GenerateOutputFile("single");
|
||||
AZLOG_INFO("Setting capture file to %s", captureFile.c_str());
|
||||
profilerSystem->CaptureFrame(captureFile);
|
||||
}
|
||||
}
|
||||
AZ_CONSOLEFREEFUNC(ProfilerCaptureFrame, AZ::ConsoleFunctorFlags::DontReplicate, "Capture a single frame of profiling data");
|
||||
|
||||
void ProfilerStartCapture([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (auto profilerSystem = ProfilerSystemInterface::Get(); profilerSystem)
|
||||
{
|
||||
AZStd::string captureFile = GenerateOutputFile("multi");
|
||||
AZLOG_INFO("Setting capture file to %s", captureFile.c_str());
|
||||
profilerSystem->StartCapture(AZStd::move(captureFile));
|
||||
}
|
||||
}
|
||||
AZ_CONSOLEFREEFUNC(ProfilerStartCapture, AZ::ConsoleFunctorFlags::DontReplicate, "Start a multi-frame capture of profiling data");
|
||||
|
||||
void ProfilerEndCapture([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (auto profilerSystem = ProfilerSystemInterface::Get(); profilerSystem)
|
||||
{
|
||||
profilerSystem->EndCapture();
|
||||
}
|
||||
}
|
||||
AZ_CONSOLEFREEFUNC(ProfilerEndCapture, AZ::ConsoleFunctorFlags::DontReplicate, "End and dump an in-progress continuous capture");
|
||||
|
||||
AZ::IO::FixedMaxPathString GetProfilerCaptureLocation()
|
||||
{
|
||||
AZ::IO::FixedMaxPathString captureOutput;
|
||||
if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry)
|
||||
{
|
||||
settingsRegistry->Get(captureOutput, RegistryKey_ProfilerCaptureLocation);
|
||||
}
|
||||
|
||||
if (captureOutput.empty())
|
||||
{
|
||||
captureOutput = ProfilerCaptureLocationFallback;
|
||||
}
|
||||
|
||||
return captureOutput;
|
||||
}
|
||||
} // namespace AZ::Debug
|
||||
|
||||
@@ -9,11 +9,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
//! settings registry entry for specifying where to output profiler captures
|
||||
static constexpr const char* RegistryKey_ProfilerCaptureLocation = "/O3DE/AzCore/Debug/Profiler/CaptureLocation";
|
||||
|
||||
//! fallback value in the event the settings registry isn't ready or doesn't contain the key
|
||||
static constexpr const char* ProfilerCaptureLocationFallback = "@user@/Profiler";
|
||||
|
||||
/**
|
||||
* ProfilerNotifications provides a profiler event interface that can be used to update listeners on profiler status
|
||||
*/
|
||||
@@ -23,32 +32,38 @@ namespace AZ
|
||||
public:
|
||||
virtual ~ProfilerNotifications() = default;
|
||||
|
||||
virtual void OnProfileSystemInitialized() = 0;
|
||||
//! Notify when the current profiler capture is finished
|
||||
//! @param result Set to true if it's finished successfully
|
||||
//! @param info The output file path or error information which depends on the return.
|
||||
virtual void OnCaptureFinished(bool result, const AZStd::string& info) = 0;
|
||||
};
|
||||
using ProfilerNotificationBus = AZ::EBus<ProfilerNotifications>;
|
||||
|
||||
enum class ProfileFrameAdvanceType
|
||||
{
|
||||
Game,
|
||||
Render,
|
||||
Default = Game
|
||||
};
|
||||
|
||||
/**
|
||||
* ProfilerRequests provides an interface for making profiling system requests
|
||||
*/
|
||||
class ProfilerRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// Allow multiple threads to concurrently make requests
|
||||
using MutexType = AZStd::mutex;
|
||||
|
||||
AZ_RTTI(ProfilerRequests, "{90AEC117-14C1-4BAE-9704-F916E49EF13F}");
|
||||
virtual ~ProfilerRequests() = default;
|
||||
|
||||
virtual bool IsActive() = 0;
|
||||
virtual void FrameAdvance(ProfileFrameAdvanceType type) = 0;
|
||||
//! Getter/setter for the profiler active state
|
||||
virtual bool IsActive() const = 0;
|
||||
virtual void SetActive(bool active) = 0;
|
||||
|
||||
//! Capture a single frame of profiling data
|
||||
virtual bool CaptureFrame(const AZStd::string& outputFilePath) = 0;
|
||||
|
||||
//! Starting/ending a multi-frame capture of profiling data
|
||||
virtual bool StartCapture(AZStd::string outputFilePath) = 0;
|
||||
virtual bool EndCapture() = 0;
|
||||
};
|
||||
using ProfilerRequestBus = AZ::EBus<ProfilerRequests>;
|
||||
}
|
||||
}
|
||||
|
||||
using ProfilerSystemInterface = AZ::Interface<ProfilerRequests>;
|
||||
|
||||
//! helper function for getting the profiler capture location from the settings registry that
|
||||
//! includes fallback handing in the event the registry value can't be determined
|
||||
AZ::IO::FixedMaxPathString GetProfilerCaptureLocation();
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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/Debug/ProfilerBus.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/RTTI/BehaviorInterfaceProxy.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
static constexpr const char* ProfilerScriptCategory = "Profiler";
|
||||
static constexpr const char* ProfilerScriptModule = "debug";
|
||||
static constexpr AZ::Script::Attributes::ScopeFlags ProfilerScriptScope = AZ::Script::Attributes::ScopeFlags::Automation;
|
||||
|
||||
class ProfilerNotificationBusHandler final
|
||||
: public ProfilerNotificationBus::Handler
|
||||
, public AZ::BehaviorEBusHandler
|
||||
{
|
||||
public:
|
||||
AZ_EBUS_BEHAVIOR_BINDER(ProfilerNotificationBusHandler, "{44161459-B816-4876-95A4-BA16DEC767D6}", AZ::SystemAllocator,
|
||||
OnCaptureFinished
|
||||
);
|
||||
|
||||
void OnCaptureFinished(bool result, const AZStd::string& info) override
|
||||
{
|
||||
Call(FN_OnCaptureFinished, result, info);
|
||||
}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<ProfilerNotificationBus>("ProfilerNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, ProfilerScriptCategory)
|
||||
->Attribute(AZ::Script::Attributes::Module, ProfilerScriptModule)
|
||||
->Attribute(AZ::Script::Attributes::Scope, ProfilerScriptScope)
|
||||
->Handler<ProfilerNotificationBusHandler>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ProfilerSystemScriptProxy
|
||||
: public BehaviorInterfaceProxy<ProfilerRequests>
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ProfilerSystemScriptProxy, "{D671FB70-8B09-4C3A-96CD-06A339F3138E}", BehaviorInterfaceProxy<ProfilerRequests>);
|
||||
|
||||
AZ_BEHAVIOR_INTERFACE(ProfilerSystemScriptProxy, ProfilerRequests);
|
||||
};
|
||||
|
||||
void ProfilerReflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->ConstantProperty("g_ProfilerSystem", ProfilerSystemScriptProxy::GetProxy)
|
||||
->Attribute(AZ::Script::Attributes::Category, ProfilerScriptCategory)
|
||||
->Attribute(AZ::Script::Attributes::Module, ProfilerScriptModule)
|
||||
->Attribute(AZ::Script::Attributes::Scope, ProfilerScriptScope);
|
||||
|
||||
behaviorContext->Class<ProfilerSystemScriptProxy>("ProfilerSystemInterface")
|
||||
->Attribute(AZ::Script::Attributes::Category, ProfilerScriptCategory)
|
||||
->Attribute(AZ::Script::Attributes::Module, ProfilerScriptModule)
|
||||
->Attribute(AZ::Script::Attributes::Scope, ProfilerScriptScope)
|
||||
|
||||
->Method("IsValid", &ProfilerSystemScriptProxy::IsValid)
|
||||
|
||||
->Method("GetCaptureLocation",
|
||||
[](ProfilerSystemScriptProxy*) -> AZStd::string
|
||||
{
|
||||
AZ::IO::FixedMaxPathString captureOutput = GetProfilerCaptureLocation();
|
||||
return AZStd::string(captureOutput.c_str(), captureOutput.length());
|
||||
})
|
||||
|
||||
->Method("IsActive", ProfilerSystemScriptProxy::WrapMethod<&ProfilerRequests::IsActive>())
|
||||
->Method("SetActive", ProfilerSystemScriptProxy::WrapMethod<&ProfilerRequests::SetActive>())
|
||||
|
||||
->Method("CaptureFrame", ProfilerSystemScriptProxy::WrapMethod<&ProfilerRequests::CaptureFrame>())
|
||||
|
||||
->Method("StartCapture", ProfilerSystemScriptProxy::WrapMethod<&ProfilerRequests::StartCapture>())
|
||||
->Method("EndCapture", ProfilerSystemScriptProxy::WrapMethod<&ProfilerRequests::EndCapture>());
|
||||
}
|
||||
|
||||
ProfilerNotificationBusHandler::Reflect(context);
|
||||
}
|
||||
} // namespace AZ::Debug
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
//! Reflects the profiler bus script bindings
|
||||
void ProfilerReflect(AZ::ReflectContext* context);
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
@@ -27,26 +27,21 @@
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Debug
|
||||
{
|
||||
namespace Debug
|
||||
struct StackFrame;
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
struct StackFrame;
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
bool AttachDebugger();
|
||||
bool IsDebuggerPresent();
|
||||
void HandleExceptions(bool isEnabled);
|
||||
void DebugBreak();
|
||||
bool AttachDebugger();
|
||||
bool IsDebuggerPresent();
|
||||
void HandleExceptions(bool isEnabled);
|
||||
void DebugBreak();
|
||||
#endif
|
||||
void Terminate(int exitCode);
|
||||
}
|
||||
void Terminate(int exitCode);
|
||||
}
|
||||
|
||||
using namespace AZ::Debug;
|
||||
|
||||
namespace DebugInternal
|
||||
{
|
||||
// other threads can trigger fatals and errors, but the same thread should not, to avoid stack overflow.
|
||||
@@ -60,7 +55,7 @@ namespace AZ
|
||||
// Globals
|
||||
const int g_maxMessageLength = 4096;
|
||||
static const char* g_dbgSystemWnd = "System";
|
||||
Trace Debug::g_tracer;
|
||||
Trace g_tracer;
|
||||
void* g_exceptionInfo = nullptr;
|
||||
|
||||
// Environment var needed to track ignored asserts across systems and disable native UI under certain conditions
|
||||
@@ -616,4 +611,4 @@ namespace AZ
|
||||
val.Set(level);
|
||||
}
|
||||
}
|
||||
} // namspace AZ
|
||||
} // namspace AZ::Debug
|
||||
|
||||
@@ -156,7 +156,10 @@ namespace AZ
|
||||
void StreamerComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
bool isEnabled = false;
|
||||
AZ::Debug::ProfilerRequestBus::BroadcastResult(isEnabled, &AZ::Debug::ProfilerRequests::IsActive);
|
||||
if (auto profilerSystem = AZ::Debug::ProfilerSystemInterface::Get(); profilerSystem)
|
||||
{
|
||||
isEnabled = profilerSystem->IsActive();
|
||||
}
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
|
||||
@@ -383,36 +383,36 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool CmpAllEq(__m128 arg1, __m128 arg2, int32_t mask)
|
||||
{
|
||||
const __m128i compare = CastToInt(CmpNeq(arg1, arg2));
|
||||
return (_mm_movemask_epi8(compare) & mask) == 0;
|
||||
const __m128 compare = CmpEq(arg1, arg2);
|
||||
return (_mm_movemask_ps(compare) & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool CmpAllLt(__m128 arg1, __m128 arg2, int32_t mask)
|
||||
{
|
||||
const __m128i compare = CastToInt(CmpGtEq(arg1, arg2));
|
||||
return (_mm_movemask_epi8(compare) & mask) == 0;
|
||||
const __m128 compare = CmpLt(arg1, arg2);
|
||||
return (_mm_movemask_ps(compare) & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool CmpAllLtEq(__m128 arg1, __m128 arg2, int32_t mask)
|
||||
{
|
||||
const __m128i compare = CastToInt(CmpGt(arg1, arg2));
|
||||
return (_mm_movemask_epi8(compare) & mask) == 0;
|
||||
const __m128 compare = CmpLtEq(arg1, arg2);
|
||||
return (_mm_movemask_ps(compare) & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool CmpAllGt(__m128 arg1, __m128 arg2, int32_t mask)
|
||||
{
|
||||
const __m128i compare = CastToInt(CmpLtEq(arg1, arg2));
|
||||
return (_mm_movemask_epi8(compare) & mask) == 0;
|
||||
const __m128 compare = CmpGt(arg1, arg2);
|
||||
return (_mm_movemask_ps(compare) & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool CmpAllGtEq(__m128 arg1, __m128 arg2, int32_t mask)
|
||||
{
|
||||
const __m128i compare = CastToInt(CmpLt(arg1, arg2));
|
||||
return (_mm_movemask_epi8(compare) & mask) == 0;
|
||||
const __m128 compare = CmpGtEq(arg1, arg2);
|
||||
return (_mm_movemask_ps(compare) & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -331,31 +331,32 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0x000F);
|
||||
// Only check the first bit for Vector1
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLt(arg1, arg2, 0x000F);
|
||||
return Sse::CmpAllLt(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0x000F);
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGt(arg1, arg2, 0x000F);
|
||||
return Sse::CmpAllGt(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0x000F);
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
@@ -397,7 +398,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec1::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0x000F);
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b0001);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -383,31 +383,32 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec2::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0x00FF);
|
||||
// Only check the first two bits for Vector2
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b0011);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec2::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLt(arg1, arg2, 0x00FF);
|
||||
return Sse::CmpAllLt(arg1, arg2, 0b0011);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec2::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0x00FF);
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0b0011);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec2::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGt(arg1, arg2, 0x00FF);
|
||||
return Sse::CmpAllGt(arg1, arg2, 0b0011);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec2::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0x00FF);
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0b0011);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -419,31 +419,32 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0x0FFF);
|
||||
// Only check the first three bits for Vector3
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLt(arg1, arg2, 0x0FFF);
|
||||
return Sse::CmpAllLt(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0x0FFF);
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGt(arg1, arg2, 0x0FFF);
|
||||
return Sse::CmpAllGt(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0x0FFF);
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
@@ -485,7 +486,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec3::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0x0FFF);
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b0111);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -455,31 +455,32 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0xFFFF);
|
||||
// Check the first four bits for Vector4
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLt(arg1, arg2, 0xFFFF);
|
||||
return Sse::CmpAllLt(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0xFFFF);
|
||||
return Sse::CmpAllLtEq(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGt(arg1, arg2, 0xFFFF);
|
||||
return Sse::CmpAllGt(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0xFFFF);
|
||||
return Sse::CmpAllGtEq(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +522,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Vec4::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
|
||||
{
|
||||
return Sse::CmpAllEq(arg1, arg2, 0xFFFF);
|
||||
return Sse::CmpAllEq(arg1, arg2, 0b1111);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,16 +10,13 @@
|
||||
#include <AzCore/Module/Internal/ModuleManagerSearchPathTool.h>
|
||||
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
@@ -221,11 +218,16 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string componentNamesArray = R"({ "SystemComponents":[)";
|
||||
const char* comma = "";
|
||||
// For all system components, deactivate
|
||||
for (auto componentIt = m_systemComponents.rbegin(); componentIt != m_systemComponents.rend(); ++componentIt)
|
||||
{
|
||||
ModuleEntity::DeactivateComponent(**componentIt);
|
||||
componentNamesArray += AZStd::string::format(R"(%s"%s")", comma, (*componentIt)->RTTI_GetTypeName());
|
||||
comma = ", ";
|
||||
}
|
||||
componentNamesArray += R"(]})";
|
||||
|
||||
// For all modules that we created an entity for, set them to "Init" (meaning not Activated)
|
||||
for (auto& moduleData : m_ownedModules)
|
||||
@@ -239,6 +241,13 @@ namespace AZ
|
||||
|
||||
// Since the system components have been deactivated clear out the vector.
|
||||
m_systemComponents.clear();
|
||||
|
||||
// Signal that the System Components have deactivated
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "SystemComponentsDeactivated", componentNamesArray);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -284,7 +293,11 @@ namespace AZ
|
||||
{
|
||||
// Split the tag list
|
||||
AZStd::vector<AZStd::string_view> tagList;
|
||||
AZStd::tokenize<AZStd::string_view>(tags, ",", tagList);
|
||||
auto TokenizeTags = [&tagList](AZStd::string_view token)
|
||||
{
|
||||
tagList.push_back(token);
|
||||
};
|
||||
AZ::StringFunc::TokenizeVisitor(tags, TokenizeTags, ',');
|
||||
|
||||
m_systemComponentTags.resize(tagList.size());
|
||||
AZStd::transform(tagList.begin(), tagList.end(), m_systemComponentTags.begin(), [](const AZStd::string_view& tag)
|
||||
@@ -737,11 +750,17 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string componentNamesArray = R"({ "SystemComponents":[)";
|
||||
const char* comma = "";
|
||||
// Activate the entities in the appropriate order
|
||||
for (Component* component : componentsToActivate)
|
||||
{
|
||||
ModuleEntity::ActivateComponent(*component);
|
||||
|
||||
componentNamesArray += AZStd::string::format(R"(%s"%s")", comma, component->RTTI_GetTypeName());
|
||||
comma = ", ";
|
||||
}
|
||||
componentNamesArray += R"(]})";
|
||||
|
||||
// Done activating; set state to active
|
||||
for (auto& moduleData : modulesToInit)
|
||||
@@ -755,5 +774,12 @@ namespace AZ
|
||||
|
||||
// Save the activated components for deactivation later
|
||||
m_systemComponents.insert(m_systemComponents.end(), componentsToActivate.begin(), componentsToActivate.end());
|
||||
|
||||
// Signal that the System Components are activated
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "SystemComponentsActivated",
|
||||
componentNamesArray);
|
||||
}
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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/Interface/Interface.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/std/typetraits/function_traits.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
/**
|
||||
* Utility class for reflecting an AZ::Interface through the BehaviorContext
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* class MyInterface
|
||||
* {
|
||||
* public:
|
||||
* AZ_RTTI(MyInterface, "{BADDF000D-CDCD-CDCD-CDCD-BAAAADF0000D}");
|
||||
* virtual ~MyInterface() = default;
|
||||
*
|
||||
* virtual AZStd::string Foo() = 0;
|
||||
* virtual void Bar(float x, float y) = 0;
|
||||
* };
|
||||
*
|
||||
* class MySystemProxy
|
||||
* : public BehaviorInterfaceProxy<MyInterface>
|
||||
* {
|
||||
* public:
|
||||
* AZ_RTTI(MySystemProxy, "{CDCDCDCD-BAAD-BADD-F00D-CDCDCDCDCDCD}", BehaviorInterfaceProxy<MyInterface>);
|
||||
* AZ_BEHAVIOR_INTERFACE(MySystemProxy, MyInterface);
|
||||
* };
|
||||
*
|
||||
* void Reflect(AZ::ReflectContext* context)
|
||||
* {
|
||||
* if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
* {
|
||||
* behaviorContext->ConstantProperty("g_MySystem", MySystemProxy::GetProxy)
|
||||
* ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
* ->Attribute(AZ::Script::Attributes::Module, "MyModule");
|
||||
*
|
||||
* behaviorContext->Class<MySystemProxy>("MySystemInterface")
|
||||
* ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
* ->Attribute(AZ::Script::Attributes::Module, "MyModule")
|
||||
*
|
||||
* ->Method("Foo", MySystemProxy::WrapMethod<&MyInterface::Foo>())
|
||||
* ->Method("Bar", MySystemProxy::WrapMethod<&MyInterface::Bar>());
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
template<typename T>
|
||||
class BehaviorInterfaceProxy
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BehaviorInterfaceProxy, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(BehaviorInterfaceProxy<T>, "{E7CC8D27-4499-454E-A7DF-3F72FBECD30D}");
|
||||
|
||||
BehaviorInterfaceProxy() = default;
|
||||
virtual ~BehaviorInterfaceProxy() = default;
|
||||
|
||||
//! Stores the instance which will use the provided shared_ptr deleter when the reference count hits zero
|
||||
BehaviorInterfaceProxy(AZStd::shared_ptr<T> sharedInstance)
|
||||
: m_instance(AZStd::move(sharedInstance))
|
||||
{
|
||||
}
|
||||
|
||||
//! Stores the instance which will perform a no-op deleter when the reference count hits zero
|
||||
BehaviorInterfaceProxy(T* rawIntance)
|
||||
: m_instance(rawIntance, [](T*) {})
|
||||
{
|
||||
}
|
||||
|
||||
//! Returns if the m_instance shared pointer is non-nullptr
|
||||
bool IsValid() const { return m_instance; }
|
||||
|
||||
protected:
|
||||
//! Internal access for use in the derived GetProxy function
|
||||
static T* GetInstance()
|
||||
{
|
||||
T* interfacePtr = AZ::Interface<T>::Get();
|
||||
AZ_Warning("BehaviorInterfaceProxy", interfacePtr,
|
||||
"There is currently no global %s registered with an AZ Interface<T>",
|
||||
AzTypeInfo<T>::Name()
|
||||
);
|
||||
// Don't delete the global instance, it is not owned by the behavior context
|
||||
return interfacePtr;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
struct MethodWrapper
|
||||
{
|
||||
template<typename Proxy, auto Method>
|
||||
static auto WrapMethod()
|
||||
{
|
||||
using ReturnType = AZStd::function_traits_get_result_t<AZStd::remove_cvref_t<decltype(Method)>>;
|
||||
return [](Proxy* proxy, Args... params) -> ReturnType
|
||||
{
|
||||
if (proxy && proxy->IsValid())
|
||||
{
|
||||
return AZStd::invoke(Method, proxy->m_instance, AZStd::forward<Args>(params)...);
|
||||
}
|
||||
return ReturnType();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
AZStd::shared_ptr<T> m_instance;
|
||||
};
|
||||
|
||||
#define AZ_BEHAVIOR_INTERFACE(ProxyType, InterfaceType) \
|
||||
static ProxyType GetProxy() { return GetInstance(); } \
|
||||
template<auto Method> \
|
||||
static auto WrapMethod() { \
|
||||
using FuncTraits = AZStd::function_traits<AZStd::remove_cvref_t<decltype(Method)>>; \
|
||||
return FuncTraits::template expand_args<MethodWrapper>::template WrapMethod<ProxyType, Method>(); \
|
||||
} \
|
||||
ProxyType() = default; \
|
||||
ProxyType(AZStd::shared_ptr<InterfaceType> sharedInstance) : BehaviorInterfaceProxy(sharedInstance) {} \
|
||||
ProxyType(InterfaceType* rawIntance) : BehaviorInterfaceProxy(rawIntance) {}
|
||||
} // namespace AZ
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Debug/ProfilerReflection.h>
|
||||
#include <AzCore/Debug/TraceReflection.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/Math/MathReflection.h>
|
||||
@@ -87,6 +88,8 @@ void ScriptSystemComponent::Activate()
|
||||
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, "lua");
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, "luac");
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(
|
||||
&AZ::Data::AssetCatalogRequests::EnableCatalogForAsset, AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
|
||||
|
||||
if (Data::AssetManager::Instance().IsReady())
|
||||
{
|
||||
@@ -925,6 +928,7 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection)
|
||||
// reflect default entity
|
||||
MathReflect(behaviorContext);
|
||||
ScriptDebug::Reflect(behaviorContext);
|
||||
Debug::ProfilerReflect(behaviorContext);
|
||||
Debug::TraceReflect(behaviorContext);
|
||||
|
||||
behaviorContext->Class<PlatformID>("Platform")
|
||||
|
||||
@@ -634,12 +634,18 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
|
||||
// Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name.
|
||||
auto projectNameKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
constexpr auto projectNameKey =
|
||||
FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
+ "/project_name";
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
if (!registry.Get(projectName, projectNameKey))
|
||||
// Read the project name from the project.json file if it exists
|
||||
if (AZ::IO::FixedMaxPath projectJsonPath = normalizedProjectPath / "project.json";
|
||||
AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
registry.MergeSettingsFile(projectJsonPath.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
}
|
||||
if (FixedValueString projectName; !registry.Get(projectName, projectNameKey))
|
||||
{
|
||||
projectName = path.Filename().Native();
|
||||
registry.Set(projectNameKey, projectName);
|
||||
|
||||
@@ -15,20 +15,20 @@
|
||||
|
||||
namespace AZ::SettingsRegistryScriptUtils::Internal
|
||||
{
|
||||
static void RegisterScriptProxyForNotify(SettingsRegistryScriptProxy& settingsRegistryProxy)
|
||||
static void RegisterScriptProxyForNotify(SettingsRegistryInterface* settingsRegistry,
|
||||
SettingsRegistryScriptProxy::NotifyEventProxy* notifyEventProxy)
|
||||
{
|
||||
if (settingsRegistryProxy.IsValid())
|
||||
if (settingsRegistry != nullptr)
|
||||
{
|
||||
auto ForwardSettingsUpdateToProxyEvent = [&settingsRegistryProxy](AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
auto ForwardSettingsUpdateToProxyEvent = [notifyEventProxy](AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
if (settingsRegistryProxy.m_notifyEventProxy)
|
||||
if (notifyEventProxy)
|
||||
{
|
||||
settingsRegistryProxy.m_notifyEventProxy->m_scriptNotifyEvent.Signal(path);
|
||||
notifyEventProxy->m_scriptNotifyEvent.Signal(path);
|
||||
}
|
||||
};
|
||||
// Register the forwarding function with the BehaviorContext
|
||||
settingsRegistryProxy.m_notifyEventProxy->m_settingsUpdatedHandler =
|
||||
settingsRegistryProxy.m_settingsRegistry->RegisterNotifier(ForwardSettingsUpdateToProxyEvent);
|
||||
notifyEventProxy->m_settingsUpdatedHandler = settingsRegistry->RegisterNotifier(ForwardSettingsUpdateToProxyEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace AZ::SettingsRegistryScriptUtils::Internal
|
||||
: m_settingsRegistry(AZStd::move(settingsRegistry))
|
||||
, m_notifyEventProxy(AZStd::make_shared<NotifyEventProxy>())
|
||||
{
|
||||
RegisterScriptProxyForNotify(*this);
|
||||
RegisterScriptProxyForNotify(m_settingsRegistry.get(), m_notifyEventProxy.get());
|
||||
}
|
||||
|
||||
// Raw AZ::SettingsRegistryInterface pointer is not owned by the proxy, so it's deleter is a no-op
|
||||
@@ -45,7 +45,7 @@ namespace AZ::SettingsRegistryScriptUtils::Internal
|
||||
: m_settingsRegistry(settingsRegistry, [](AZ::SettingsRegistryInterface*) {})
|
||||
, m_notifyEventProxy(AZStd::make_shared<NotifyEventProxy>())
|
||||
{
|
||||
RegisterScriptProxyForNotify(*this);
|
||||
RegisterScriptProxyForNotify(m_settingsRegistry.get(), m_notifyEventProxy.get());
|
||||
}
|
||||
|
||||
// SettingsRegistryScriptProxy function that determines if the SettingsRegistry object is valid
|
||||
|
||||
@@ -363,7 +363,11 @@ namespace AZ
|
||||
{
|
||||
++m_graphsRemaining;
|
||||
|
||||
event->m_executor = this; // Used to validate event is not waited for inside a job
|
||||
if (event)
|
||||
{
|
||||
event->IncWaitCount();
|
||||
event->m_executor = this; // Used to validate event is not waited for inside a job
|
||||
}
|
||||
|
||||
// Submit all tasks that have no inbound edges
|
||||
for (Internal::Task& task : graph.Tasks())
|
||||
|
||||
@@ -20,6 +20,46 @@ namespace AZ
|
||||
m_semaphore.acquire();
|
||||
}
|
||||
|
||||
void TaskGraphEvent::IncWaitCount()
|
||||
{
|
||||
// guess zero to optimize for single task graph using an event, if multiple are using it then this will take 2+ comp_exch calls
|
||||
int expectedValue = 0;
|
||||
while(!m_waitCount.compare_exchange_weak(expectedValue, expectedValue + 1))
|
||||
{
|
||||
// value will be negative once event is ready to signal or has been signaled. Shouldn't happen.
|
||||
AZ_Assert(expectedValue >= 0, "Called TaskGraphEvent::IncWaitCount on a signalled event");
|
||||
if (expectedValue < 0) // event already signaled, skip
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void TaskGraphEvent::Signal()
|
||||
{
|
||||
// guess one to optimize for single task graph using an event, if multiple are using it then this will take 2+ comp_exch calls
|
||||
int expectedValue = 1;
|
||||
while(!m_waitCount.compare_exchange_weak(expectedValue, expectedValue - 1))
|
||||
{
|
||||
// It's an error for Signal to be called if no one is waiting, or the event has already been signaled
|
||||
AZ_Assert(expectedValue > 0, "Called TaskGraphEvent::Signal when event is either signaled or unused");
|
||||
if (expectedValue < 0) // return if already signaled
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if (expectedValue == 1) // This call to Signal decremented the value to 0.
|
||||
{
|
||||
expectedValue = 0;
|
||||
// validate no one incremented the wait count and mark signalling state
|
||||
if (m_waitCount.compare_exchange_strong(expectedValue, -1))
|
||||
{
|
||||
m_semaphore.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskToken::PrecedesInternal(TaskToken& comesAfter)
|
||||
{
|
||||
AZ_Assert(!m_parent.m_submitted, "Cannot mutate a TaskGraph that was previously submitted.");
|
||||
|
||||
@@ -61,14 +61,14 @@ namespace AZ
|
||||
uint32_t m_index;
|
||||
};
|
||||
|
||||
// A TaskGraphEvent may be used to block until a task graph has finished executing. Usage
|
||||
// A TaskGraphEvent may be used to block until one or more task graphs has finished executing. Usage
|
||||
// is NOT recommended for the majority of tasks (prefer to simply containing expanding/contracting
|
||||
// the graph without synchronization over the course of the frame). However, the event
|
||||
// is useful for the edges of the computation graph.
|
||||
//
|
||||
// You are responsible for ensuring the event object lifetime exceeds the task graph lifetime.
|
||||
//
|
||||
// After the TaskGraphEvent is signaled, you are allowed to reuse the same TaskGraphEvent
|
||||
// After the TaskGraphEvent is signaled, you are NOT allowed to reuse the same TaskGraphEvent
|
||||
// for a future submission.
|
||||
class TaskGraphEvent
|
||||
{
|
||||
@@ -81,10 +81,12 @@ namespace AZ
|
||||
friend class TaskGraph;
|
||||
friend class TaskExecutor;
|
||||
|
||||
void IncWaitCount();
|
||||
void Signal();
|
||||
|
||||
AZStd::binary_semaphore m_semaphore;
|
||||
TaskExecutor* m_executor = nullptr;
|
||||
AZStd::atomic_int m_waitCount = 0;
|
||||
TaskExecutor* m_executor = nullptr;
|
||||
};
|
||||
|
||||
// The TaskGraph encapsulates a set of tasks and their interdependencies. After adding
|
||||
|
||||
@@ -33,11 +33,6 @@ namespace AZ
|
||||
return m_semaphore.try_acquire_for(AZStd::chrono::milliseconds{ 0 });
|
||||
}
|
||||
|
||||
inline void TaskGraphEvent::Signal()
|
||||
{
|
||||
m_semaphore.release();
|
||||
}
|
||||
|
||||
template<typename Lambda>
|
||||
TaskToken TaskGraph::AddTask(TaskDescriptor const& desc, Lambda&& lambda)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,8 @@ set(FILES
|
||||
Component/ComponentApplication.cpp
|
||||
Component/ComponentApplication.h
|
||||
Component/ComponentApplicationBus.h
|
||||
Component/ComponentApplicationLifecycle.cpp
|
||||
Component/ComponentApplicationLifecycle.h
|
||||
Component/ComponentBus.cpp
|
||||
Component/ComponentBus.h
|
||||
Component/ComponentExport.h
|
||||
@@ -106,6 +108,8 @@ set(FILES
|
||||
Debug/Profiler.inl
|
||||
Debug/Profiler.h
|
||||
Debug/ProfilerBus.h
|
||||
Debug/ProfilerReflection.cpp
|
||||
Debug/ProfilerReflection.h
|
||||
Debug/StackTracer.h
|
||||
Debug/EventTrace.h
|
||||
Debug/EventTrace.cpp
|
||||
@@ -121,6 +125,8 @@ set(FILES
|
||||
Debug/TraceMessagesDrillerBus.h
|
||||
Debug/TraceReflection.cpp
|
||||
Debug/TraceReflection.h
|
||||
DOM/DomVisitor.cpp
|
||||
DOM/DomVisitor.h
|
||||
Driller/DefaultStringPool.h
|
||||
Driller/Driller.cpp
|
||||
Driller/Driller.h
|
||||
@@ -452,6 +458,7 @@ set(FILES
|
||||
RTTI/BehaviorContext.h
|
||||
RTTI/BehaviorContextUtilities.h
|
||||
RTTI/BehaviorContextUtilities.cpp
|
||||
RTTI/BehaviorInterfaceProxy.h
|
||||
RTTI/BehaviorObjectSignals.h
|
||||
RTTI/TypeSafeIntegral.h
|
||||
Script/ScriptAsset.cpp
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Debug
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo);
|
||||
@@ -26,94 +26,91 @@ namespace AZ
|
||||
|
||||
constexpr int g_maxMessageLength = 4096;
|
||||
|
||||
namespace Debug
|
||||
namespace Platform
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
bool IsDebuggerPresent()
|
||||
bool IsDebuggerPresent()
|
||||
{
|
||||
return ::IsDebuggerPresent() ? true : false;
|
||||
}
|
||||
|
||||
void HandleExceptions(bool isEnabled)
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
return ::IsDebuggerPresent() ? true : false;
|
||||
g_previousExceptionHandler = ::SetUnhandledExceptionFilter(&ExceptionHandler);
|
||||
}
|
||||
|
||||
void HandleExceptions(bool isEnabled)
|
||||
else
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
g_previousExceptionHandler = ::SetUnhandledExceptionFilter(&ExceptionHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
::SetUnhandledExceptionFilter(g_previousExceptionHandler);
|
||||
g_previousExceptionHandler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool AttachDebugger()
|
||||
{
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Launch vsjitdebugger.exe, this app is always present in System32 folder
|
||||
// with an installation of any version of visual studio.
|
||||
// It will open a debugging dialog asking the user what debugger to use
|
||||
|
||||
STARTUPINFOW startupInfo = {0};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
PROCESS_INFORMATION processInfo = {0};
|
||||
|
||||
wchar_t cmdline[MAX_PATH];
|
||||
swprintf_s(cmdline, L"vsjitdebugger.exe -p %li", ::GetCurrentProcessId());
|
||||
bool success = ::CreateProcessW(
|
||||
NULL, // No module name (use command line)
|
||||
cmdline, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // No handle inheritance
|
||||
0, // No creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&startupInfo, // Pointer to STARTUPINFO structure
|
||||
&processInfo); // Pointer to PROCESS_INFORMATION structure
|
||||
|
||||
if (success)
|
||||
{
|
||||
::WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
::CloseHandle(processInfo.hProcess);
|
||||
::CloseHandle(processInfo.hThread);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebugBreak()
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
#endif // AZ_ENABLE_DEBUG_TOOLS
|
||||
|
||||
void Terminate(int exitCode)
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), exitCode);
|
||||
}
|
||||
|
||||
void OutputToDebugger([[maybe_unused]] const char* window, const char* message)
|
||||
{
|
||||
AZStd::fixed_wstring<g_maxMessageLength> tmpW;
|
||||
if(window)
|
||||
{
|
||||
AZStd::to_wstring(tmpW, window);
|
||||
tmpW += L": ";
|
||||
OutputDebugStringW(tmpW.c_str());
|
||||
tmpW.clear();
|
||||
}
|
||||
AZStd::to_wstring(tmpW, message);
|
||||
OutputDebugStringW(tmpW.c_str());
|
||||
::SetUnhandledExceptionFilter(g_previousExceptionHandler);
|
||||
g_previousExceptionHandler = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AttachDebugger()
|
||||
{
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Launch vsjitdebugger.exe, this app is always present in System32 folder
|
||||
// with an installation of any version of visual studio.
|
||||
// It will open a debugging dialog asking the user what debugger to use
|
||||
|
||||
STARTUPINFOW startupInfo = {0};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
PROCESS_INFORMATION processInfo = {0};
|
||||
|
||||
wchar_t cmdline[MAX_PATH];
|
||||
swprintf_s(cmdline, L"vsjitdebugger.exe -p %li", ::GetCurrentProcessId());
|
||||
bool success = ::CreateProcessW(
|
||||
NULL, // No module name (use command line)
|
||||
cmdline, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // No handle inheritance
|
||||
0, // No creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&startupInfo, // Pointer to STARTUPINFO structure
|
||||
&processInfo); // Pointer to PROCESS_INFORMATION structure
|
||||
|
||||
if (success)
|
||||
{
|
||||
::WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
::CloseHandle(processInfo.hProcess);
|
||||
::CloseHandle(processInfo.hThread);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebugBreak()
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
#endif // AZ_ENABLE_DEBUG_TOOLS
|
||||
|
||||
void Terminate(int exitCode)
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), exitCode);
|
||||
}
|
||||
|
||||
void OutputToDebugger([[maybe_unused]] const char* window, const char* message)
|
||||
{
|
||||
AZStd::fixed_wstring<g_maxMessageLength> tmpW;
|
||||
if(window)
|
||||
{
|
||||
AZStd::to_wstring(tmpW, window);
|
||||
tmpW += L": ";
|
||||
OutputDebugStringW(tmpW.c_str());
|
||||
tmpW.clear();
|
||||
}
|
||||
AZStd::to_wstring(tmpW, message);
|
||||
OutputDebugStringW(tmpW.c_str());
|
||||
}
|
||||
} // namespace Platform
|
||||
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
|
||||
@@ -187,6 +184,8 @@ namespace AZ
|
||||
azsnprintf(message, g_maxMessageLength, "Exception : 0x%lX - '%s' [%p]\n", ExceptionInfo->ExceptionRecord->ExceptionCode, GetExeptionName(ExceptionInfo->ExceptionRecord->ExceptionCode), ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
Debug::Trace::Instance().Output(nullptr, message);
|
||||
|
||||
Debug::Trace::Instance().PrintCallstack(nullptr, 0, ExceptionInfo->ContextRecord);
|
||||
|
||||
EBUS_EVENT(Debug::TraceMessageDrillerBus, OnException, message);
|
||||
|
||||
bool result = false;
|
||||
@@ -198,7 +197,7 @@ namespace AZ
|
||||
// if someone ever returns TRUE we assume that they somehow handled this exception and continue.
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
Debug::Trace::Instance().PrintCallstack(nullptr, 0, ExceptionInfo->ContextRecord);
|
||||
|
||||
Debug::Trace::Instance().Output(nullptr, "==================================================================\n");
|
||||
|
||||
// allowing continue of execution is not valid here. This handler gets called for serious exceptions.
|
||||
@@ -211,4 +210,4 @@ namespace AZ
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
} // namspace AZ::Debug
|
||||
|
||||
@@ -610,15 +610,16 @@ namespace UnitTest
|
||||
g.Follows(e, f);
|
||||
g.Precedes(d);
|
||||
|
||||
TaskGraphEvent ev;
|
||||
graph.SubmitOnExecutor(*m_executor, &ev);
|
||||
ev.Wait();
|
||||
TaskGraphEvent ev1;
|
||||
graph.SubmitOnExecutor(*m_executor, &ev1);
|
||||
ev1.Wait();
|
||||
|
||||
EXPECT_EQ(3 | 0b100000, x);
|
||||
x = 0;
|
||||
|
||||
graph.SubmitOnExecutor(*m_executor, &ev);
|
||||
ev.Wait();
|
||||
TaskGraphEvent ev2;
|
||||
graph.SubmitOnExecutor(*m_executor, &ev2);
|
||||
ev2.Wait();
|
||||
|
||||
EXPECT_EQ(3 | 0b100000, x);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Component/NonUniformScaleBus.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Memory/MemoryComponent.h>
|
||||
@@ -120,6 +121,11 @@ namespace AzFramework
|
||||
m_archiveFileIO = AZStd::make_unique<AZ::IO::ArchiveFileIO>(m_archive.get());
|
||||
AZ::IO::FileIOBase::SetInstance(m_archiveFileIO.get());
|
||||
SetFileIOAliases();
|
||||
// The FileIOAvailable event needs to be registered here as this event is sent out
|
||||
// before the settings registry has merged the .setreg files from the <engine-root>
|
||||
// (That happens in MergeSettingsToRegistry
|
||||
AZ::ComponentApplicationLifecycle::RegisterEvent(*m_settingsRegistry, "FileIOAvailable");
|
||||
AZ::ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "FileIOAvailable", R"({})");
|
||||
}
|
||||
|
||||
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI == nullptr)
|
||||
@@ -172,6 +178,8 @@ namespace AzFramework
|
||||
// Archive classes relies on the FileIOBase DirectInstance to close
|
||||
// files properly
|
||||
m_directFileIO.reset();
|
||||
|
||||
AZ::ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "FileIOUnavailable", R"({})");
|
||||
}
|
||||
|
||||
void Application::Start(const Descriptor& descriptor, const StartupParameters& startupParameters)
|
||||
@@ -196,7 +204,24 @@ namespace AzFramework
|
||||
systemEntity->Activate();
|
||||
AZ_Assert(systemEntity->GetState() == AZ::Entity::State::Active, "System Entity failed to activate.");
|
||||
|
||||
m_isStarted = (systemEntity->GetState() == AZ::Entity::State::Active);
|
||||
if (m_isStarted = (systemEntity->GetState() == AZ::Entity::State::Active); m_isStarted)
|
||||
{
|
||||
if (m_startupParameters.m_loadAssetCatalog)
|
||||
{
|
||||
// Start Monitoring Asset changes over the network and load the AssetCatalog
|
||||
auto StartMonitoringAssetsAndLoadCatalog = [this](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
|
||||
{
|
||||
if (AZ::IO::FixedMaxPath assetCatalogPath;
|
||||
m_settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
|
||||
{
|
||||
assetCatalogPath /= "assetcatalog.xml";
|
||||
assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str());
|
||||
}
|
||||
};
|
||||
using AssetCatalogBus = AZ::Data::AssetCatalogRequestBus;
|
||||
AssetCatalogBus::Broadcast(AZStd::move(StartMonitoringAssetsAndLoadCatalog));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::PreModuleLoad()
|
||||
@@ -210,6 +235,17 @@ namespace AzFramework
|
||||
{
|
||||
if (m_isStarted)
|
||||
{
|
||||
if (m_startupParameters.m_loadAssetCatalog)
|
||||
{
|
||||
// Stop Monitoring Assets changes
|
||||
auto StopMonitoringAssets = [](AZ::Data::AssetCatalogRequests* assetCatalogRequests)
|
||||
{
|
||||
assetCatalogRequests->StopMonitoringAssets();
|
||||
};
|
||||
using AssetCatalogBus = AZ::Data::AssetCatalogRequestBus;
|
||||
AssetCatalogBus::Broadcast(AZStd::move(StopMonitoringAssets));
|
||||
}
|
||||
|
||||
ApplicationLifecycleEvents::Bus::Broadcast(&ApplicationLifecycleEvents::OnApplicationAboutToStop);
|
||||
|
||||
m_pimpl.reset();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
@@ -363,6 +364,23 @@ namespace AZ::IO
|
||||
, m_mainThreadId{ AZStd::this_thread::get_id() }
|
||||
{
|
||||
CompressionBus::Handler::BusConnect();
|
||||
|
||||
// If the settings registry is not available at this point,
|
||||
// then something catastrophic has happened in the application startup.
|
||||
// That should have been caught and messaged out earlier in startup.
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
// Automatically register the event if it's not registered, because
|
||||
// this system is initialized before the settings registry has loaded the event list.
|
||||
AZ::ComponentApplicationLifecycle::RegisterHandler(
|
||||
*settingsRegistry, m_componentApplicationLifecycleHandler,
|
||||
[this](AZStd::string_view /*path*/, AZ::SettingsRegistryInterface::Type /*type*/)
|
||||
{
|
||||
OnSystemEntityActivated();
|
||||
},
|
||||
"SystemComponentsActivated",
|
||||
/*autoRegisterEvent*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1175,13 +1193,20 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
auto bundleManifest = GetBundleManifest(desc.pZip);
|
||||
AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog;
|
||||
auto bundleManifest = GetBundleManifest(desc.pZip);
|
||||
if (bundleManifest)
|
||||
{
|
||||
bundleCatalog = GetBundleCatalog(desc.pZip, bundleManifest->GetCatalogName());
|
||||
}
|
||||
|
||||
// If this archive is loaded before the serialize context is available, then the manifest and catalog will need to be loaded later.
|
||||
if (!bundleManifest || !bundleCatalog)
|
||||
{
|
||||
m_archivesWithCatalogsToLoad.push_back(
|
||||
ArchivesWithCatalogsToLoad(szFullPath, szBindRoot, flags, nextBundle, desc.m_strFileName));
|
||||
}
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
@@ -1219,12 +1244,17 @@ namespace AZ::IO
|
||||
m_levelOpenEvent.Signal(levelDirs);
|
||||
}
|
||||
|
||||
AZ::IO::ArchiveNotificationBus::Broadcast([](AZ::IO::ArchiveNotifications* archiveNotifications, const char* bundleName,
|
||||
AZStd::shared_ptr<AzFramework::AssetBundleManifest> bundleManifest, const AZ::IO::FixedMaxPath& nextBundle, AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog)
|
||||
if (bundleManifest && bundleCatalog)
|
||||
{
|
||||
archiveNotifications->BundleOpened(bundleName, bundleManifest, nextBundle.c_str(), bundleCatalog);
|
||||
}, desc.m_strFileName.c_str(), bundleManifest, nextBundle, bundleCatalog);
|
||||
|
||||
AZ::IO::ArchiveNotificationBus::Broadcast(
|
||||
[](AZ::IO::ArchiveNotifications* archiveNotifications, const char* bundleName,
|
||||
AZStd::shared_ptr<AzFramework::AssetBundleManifest> bundleManifest, const AZ::IO::FixedMaxPath& nextBundle,
|
||||
AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog)
|
||||
{
|
||||
archiveNotifications->BundleOpened(bundleName, bundleManifest, nextBundle.c_str(), bundleCatalog);
|
||||
},
|
||||
desc.m_strFileName.c_str(), bundleManifest, nextBundle, bundleCatalog);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2138,7 +2168,7 @@ namespace AZ::IO
|
||||
}
|
||||
|
||||
currentDirPattern = currentDir + AZ_FILESYSTEM_SEPARATOR_WILDCARD;
|
||||
currentFilePattern = currentDir + AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING + "levels.pak";
|
||||
currentFilePattern = currentDir + AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING + "level.pak";
|
||||
|
||||
ZipDir::FileEntry* fileEntry = findFile.FindExact(currentFilePattern.c_str());
|
||||
if (fileEntry)
|
||||
@@ -2175,4 +2205,36 @@ namespace AZ::IO
|
||||
|
||||
return catalogInfo;
|
||||
}
|
||||
|
||||
void Archive::OnSystemEntityActivated()
|
||||
{
|
||||
for (const auto& archiveInfo : m_archivesWithCatalogsToLoad)
|
||||
{
|
||||
AZStd::intrusive_ptr<INestedArchive> archive =
|
||||
OpenArchive(archiveInfo.m_fullPath, archiveInfo.m_bindRoot, archiveInfo.m_flags, nullptr);
|
||||
if (!archive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ZipDir::CachePtr pZip = static_cast<NestedArchive*>(archive.get())->GetCache();
|
||||
|
||||
AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog;
|
||||
auto bundleManifest = GetBundleManifest(pZip);
|
||||
if (bundleManifest)
|
||||
{
|
||||
bundleCatalog = GetBundleCatalog(pZip, bundleManifest->GetCatalogName());
|
||||
}
|
||||
|
||||
AZ::IO::ArchiveNotificationBus::Broadcast(
|
||||
[](AZ::IO::ArchiveNotifications* archiveNotifications, const char* bundleName,
|
||||
AZStd::shared_ptr<AzFramework::AssetBundleManifest> bundleManifest, const AZ::IO::FixedMaxPath& nextBundle,
|
||||
AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog)
|
||||
{
|
||||
archiveNotifications->BundleOpened(bundleName, bundleManifest, nextBundle.c_str(), bundleCatalog);
|
||||
},
|
||||
archiveInfo.m_strFileName.c_str(), bundleManifest, archiveInfo.m_nextBundle, bundleCatalog);
|
||||
}
|
||||
m_archivesWithCatalogsToLoad.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <AzCore/IO/CompressionBus.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
@@ -271,6 +272,11 @@ namespace AZ::IO
|
||||
ZipDir::CachePtr* pZip = {}) const;
|
||||
private:
|
||||
|
||||
// Archives can't be fully mounted until the system entity has been activated,
|
||||
// because mounting them requires the BundlingSystemComponent and the serialization system
|
||||
// to both be available.
|
||||
void OnSystemEntityActivated();
|
||||
|
||||
bool OpenPackCommon(AZStd::string_view szBindRoot, AZStd::string_view pName, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, bool addLevels = true);
|
||||
bool OpenPacksCommon(AZStd::string_view szDir, AZStd::string_view pWildcardIn, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr, bool addLevels = true);
|
||||
|
||||
@@ -313,6 +319,8 @@ namespace AZ::IO
|
||||
mutable AZStd::shared_mutex m_csZips;
|
||||
ZipArray m_arrZips;
|
||||
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_componentApplicationLifecycleHandler;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Opened files collector.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -339,5 +347,34 @@ namespace AZ::IO
|
||||
// [LYN-2376] Remove once legacy slice support is removed
|
||||
LevelPackOpenEvent m_levelOpenEvent;
|
||||
LevelPackCloseEvent m_levelCloseEvent;
|
||||
|
||||
// If pak files are loaded before the serialization and bundling system
|
||||
// are ready to go, their asset catalogs can't be loaded.
|
||||
// In this case, cache information about those archives,
|
||||
// and attempt to load the catalogs later, when the required systems are enabled.
|
||||
struct ArchivesWithCatalogsToLoad
|
||||
{
|
||||
ArchivesWithCatalogsToLoad(
|
||||
AZStd::string_view fullPath,
|
||||
AZStd::string_view bindRoot,
|
||||
int flags,
|
||||
AZ::IO::PathView nextBundle,
|
||||
AZ::IO::Path strFileName)
|
||||
: m_fullPath(fullPath)
|
||||
, m_bindRoot(bindRoot)
|
||||
, m_flags(flags)
|
||||
, m_nextBundle(nextBundle)
|
||||
, m_strFileName(strFileName)
|
||||
{
|
||||
}
|
||||
|
||||
AZ::IO::Path m_strFileName;
|
||||
AZStd::string m_fullPath;
|
||||
AZStd::string m_bindRoot;
|
||||
AZ::IO::PathView m_nextBundle;
|
||||
int m_flags;
|
||||
};
|
||||
|
||||
AZStd::vector<ArchivesWithCatalogsToLoad> m_archivesWithCatalogsToLoad;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -565,7 +565,7 @@ namespace AzFramework
|
||||
|
||||
if (!bytes.empty())
|
||||
{
|
||||
AZStd::shared_ptr < AzFramework::AssetRegistry> prevRegistry;
|
||||
AZStd::shared_ptr<AzFramework::AssetRegistry> prevRegistry;
|
||||
if (!m_initialized)
|
||||
{
|
||||
// First time initialization may have updates already processed which we want to apply
|
||||
@@ -589,7 +589,6 @@ namespace AzFramework
|
||||
AZ_TracePrintf("AssetCatalog", "Loaded registry containing %u assets.\n", m_registry->m_assetIdToInfo.size());
|
||||
|
||||
// It's currently possible in tools for us to have received updates from AP which were applied before the catalog was ready to load
|
||||
// due to CryPak and CrySystem coming online later than our components
|
||||
if (!m_initialized)
|
||||
{
|
||||
ApplyDeltaCatalog(prevRegistry);
|
||||
@@ -611,12 +610,13 @@ namespace AzFramework
|
||||
// the mutex. If the listener tries to perform a blocking asset load via GetAsset() / BlockUntilLoadComplete(), the spawned asset
|
||||
// thread will make a call to the AssetCatalogRequestBus and block on the held mutex. This would cause a deadlock, since the listener
|
||||
// won't free the mutex until the load is complete.
|
||||
// So instead, queue the notification until the next tick, so that it doesn't occur within the AssetCatalogRequestBus mutex, and also
|
||||
// So instead, queue the notification until after the AssetCatalogRequestBus mutex is unlocked for the current thread, and also
|
||||
// so that the entire AssetCatalog initialization is complete.
|
||||
AZ::TickBus::QueueFunction([catalogRegistryString = AZStd::string(catalogRegistryFile)]()
|
||||
{
|
||||
AssetCatalogEventBus::Broadcast(&AssetCatalogEventBus::Events::OnCatalogLoaded, catalogRegistryString.c_str());
|
||||
});
|
||||
auto OnCatalogLoaded = [catalogRegistryString = AZStd::string(catalogRegistryFile)]()
|
||||
{
|
||||
AssetCatalogEventBus::Broadcast(&AssetCatalogEventBus::Events::OnCatalogLoaded, catalogRegistryString.c_str());
|
||||
};
|
||||
AZ::Data::AssetCatalogRequestBus::QueueFunction(AZStd::move(OnCatalogLoaded));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,6 +978,7 @@ namespace AzFramework
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_registryMutex);
|
||||
|
||||
m_registry->Clear();
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace AzFramework
|
||||
//=========================================================================
|
||||
void AssetRegistry::Clear()
|
||||
{
|
||||
m_assetDependencies = {};
|
||||
m_assetIdToInfo = AssetIdToInfoMap();
|
||||
m_assetPathToId = AssetPathToIdMap();
|
||||
}
|
||||
|
||||
@@ -323,6 +323,13 @@ namespace AzFramework
|
||||
return localZ;
|
||||
}
|
||||
|
||||
void TransformComponent::SetWorldRotation(const AZ::Vector3& eulerAnglesRadian)
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateFromEulerAnglesRadians(eulerAnglesRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace AzFramework
|
||||
float GetLocalZ() override;
|
||||
|
||||
// Rotation modifiers
|
||||
void SetWorldRotation(const AZ::Vector3& eulerAnglesRadian) override;
|
||||
void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override;
|
||||
|
||||
AZ::Vector3 GetWorldRotation() override;
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzCore/std/string/regex.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/XML/rapidxml.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Asset/FileTagAsset.h>
|
||||
@@ -89,19 +89,19 @@ namespace AzFramework
|
||||
bool FileTagManager::Save(FileTagType fileTagType, const AZStd::string& destinationFilePath = AZStd::string())
|
||||
{
|
||||
AzFramework::FileTag::FileTagAsset* fileTagAsset = GetFileTagAsset(fileTagType);
|
||||
AZStd::string filePathToSave = destinationFilePath;
|
||||
AZ::IO::Path filePathToSave = destinationFilePath;
|
||||
if (filePathToSave.empty())
|
||||
{
|
||||
filePathToSave = FileTagQueryManager::GetDefaultFileTagFilePath(fileTagType);
|
||||
}
|
||||
|
||||
if (!AzFramework::StringFunc::EndsWith(filePathToSave, AzFramework::FileTag::FileTagAsset::Extension()))
|
||||
if (!filePathToSave.Extension().Native().ends_with(AzFramework::FileTag::FileTagAsset::Extension()))
|
||||
{
|
||||
AZ_Error("FileTag", false, "Unable to save tag file (%s). Invalid file extension, file tag can only have (%s) extension.\n", filePathToSave.c_str(), AzFramework::FileTag::FileTagAsset::Extension());
|
||||
return false;
|
||||
}
|
||||
|
||||
return AZ::Utils::SaveObjectToFile(filePathToSave, AZ::DataStream::StreamType::ST_XML, fileTagAsset);
|
||||
return AZ::Utils::SaveObjectToFile(filePathToSave.Native(), AZ::DataStream::StreamType::ST_XML, fileTagAsset);
|
||||
}
|
||||
|
||||
AZ::Outcome<AZStd::string, AZStd::string> FileTagManager::AddTagsInternal(AZStd::string filePath, FileTagType fileTagType, AZStd::vector<AZStd::string> fileTags, AzFramework::FileTag::FilePatternType filePatternType)
|
||||
@@ -239,17 +239,22 @@ namespace AzFramework
|
||||
QueryFileTagsEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZStd::string FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType fileTagType)
|
||||
AZ::IO::Path FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType fileTagType)
|
||||
{
|
||||
auto destinationFilePath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / EngineAssetSourceRelPath;
|
||||
AZ::IO::Path destinationFilePath;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Get(destinationFilePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
|
||||
}
|
||||
destinationFilePath /= EngineAssetSourceRelPath;
|
||||
destinationFilePath /= fileTagType == FileTagType::Exclude ? ExcludeFileName : IncludeFileName;
|
||||
destinationFilePath.ReplaceExtension(AzFramework::FileTag::FileTagAsset::Extension());
|
||||
return destinationFilePath.String();
|
||||
return destinationFilePath;
|
||||
}
|
||||
|
||||
bool FileTagQueryManager::Load(const AZStd::string& filePath)
|
||||
{
|
||||
AZStd::string fileToLoad = filePath;
|
||||
AZ::IO::Path fileToLoad = filePath;
|
||||
if (fileToLoad.empty())
|
||||
{
|
||||
fileToLoad = GetDefaultFileTagFilePath(m_fileTagType);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzFramework/FileTag/FileTagBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -88,7 +89,7 @@ namespace AzFramework
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static AZStd::string GetDefaultFileTagFilePath(FileTagType fileTagType);
|
||||
static AZ::IO::Path GetDefaultFileTagFilePath(FileTagType fileTagType);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/XML/rapidxml.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -66,7 +67,8 @@ namespace AzFramework
|
||||
m_excludeFileQueryManager.reset(aznew FileTagQueryManager(FileTagType::Exclude));
|
||||
if (!m_excludeFileQueryManager.get()->Load())
|
||||
{
|
||||
AZ_Error("FileTagQueryComponent", false, "Not able to load default exclude file (%s). Please make sure that it exists on disk.\n", FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType::Exclude).c_str());
|
||||
AZ_Error("FileTagQueryComponent", false, "Not able to load default exclude file (%s). Please make sure that it exists on disk.\n",
|
||||
FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType::Exclude).c_str());
|
||||
}
|
||||
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
|
||||
+5
-13
@@ -229,17 +229,13 @@ namespace AzFramework
|
||||
//! Alias for the EBus implementation of this interface
|
||||
using Bus = AZ::EBus<InputDeviceImplementationRequest<InputDeviceType>>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create the custom implementations
|
||||
using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Set a custom implementation for this input device type, either for a specific instance
|
||||
//! by addressing the call to an InputDeviceId, or for all existing instances by broadcast.
|
||||
//! Passing InputDeviceType::Implementation::Create as the argument will create the default
|
||||
//! device implementation, while passing nullptr will delete any existing implementation.
|
||||
//! \param[in] createFunction Pointer to the function that will create the implementation.
|
||||
virtual void SetCustomImplementation(CreateFunctionType createFunction) = 0;
|
||||
//! \param[in] implementationFactory Pointer to the function that creates the implementation.
|
||||
virtual void SetCustomImplementation(typename InputDeviceType::ImplementationFactory implementationFactory) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -267,18 +263,14 @@ namespace AzFramework
|
||||
AZ_DISABLE_COPY_MOVE(InputDeviceImplementationRequestHandler);
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create the custom implementations
|
||||
using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref InputDeviceImplementationRequest<InputDeviceType>::SetCustomImplementation
|
||||
AZ_INLINE void SetCustomImplementation(CreateFunctionType createFunction) override
|
||||
AZ_INLINE void SetCustomImplementation(typename InputDeviceType::ImplementationFactory implementationFactory) override
|
||||
{
|
||||
AZStd::unique_ptr<typename InputDeviceType::Implementation> newImplementation;
|
||||
if (createFunction)
|
||||
if (implementationFactory)
|
||||
{
|
||||
newImplementation.reset(createFunction(m_inputDevice));
|
||||
newImplementation.reset(implementationFactory(m_inputDevice));
|
||||
}
|
||||
m_inputDevice.SetImplementation(AZStd::move(newImplementation));
|
||||
}
|
||||
|
||||
+10
-3
@@ -94,7 +94,14 @@ namespace AzFramework
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceGamepad::InputDeviceGamepad(AZ::u32 index)
|
||||
: InputDevice(InputDeviceId(Name, index))
|
||||
: InputDeviceGamepad(InputDeviceId(Name, index)) // Delegated constructor
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceGamepad::InputDeviceGamepad(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_allChannelsById()
|
||||
, m_buttonChannelsById()
|
||||
, m_triggerChannelsById()
|
||||
@@ -144,8 +151,8 @@ namespace AzFramework
|
||||
m_thumbStickDirectionChannelsById[channelId] = channel;
|
||||
}
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
|
||||
// Connect to the haptic feedback request bus
|
||||
InputHapticFeedbackRequestBus::Handler::BusConnect(GetInputDeviceId());
|
||||
|
||||
@@ -182,6 +182,14 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceGamepad&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
explicit InputDeviceGamepad();
|
||||
@@ -191,6 +199,13 @@ namespace AzFramework
|
||||
//! \param[in] index Index of the game-pad device
|
||||
explicit InputDeviceGamepad(AZ::u32 index);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
//! \param[in] inputDeviceId Id of the input device
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceGamepad(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
AZ_DISABLE_COPY_MOVE(InputDeviceGamepad);
|
||||
|
||||
+5
-4
@@ -182,8 +182,9 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceKeyboard::InputDeviceKeyboard(AzFramework::InputDeviceId id)
|
||||
: InputDevice(id)
|
||||
InputDeviceKeyboard::InputDeviceKeyboard(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_modifierKeyStates(AZStd::make_shared<ModifierKeyStates>())
|
||||
, m_allChannelsById()
|
||||
, m_keyChannelsById()
|
||||
@@ -203,8 +204,8 @@ namespace AzFramework
|
||||
m_keyChannelsById[channelId] = channel;
|
||||
}
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
|
||||
// Connect to the text entry request bus
|
||||
InputTextEntryRequestBus::Handler::BusConnect(GetInputDeviceId());
|
||||
|
||||
+12
-1
@@ -370,9 +370,20 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceKeyboard&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
InputDeviceKeyboard(AzFramework::InputDeviceId id = Id);
|
||||
//! \param[in] inputDeviceId Optional override of the default input device id
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceKeyboard(const InputDeviceId& inputDeviceId = Id,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
|
||||
@@ -60,8 +60,9 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceMotion::InputDeviceMotion()
|
||||
: InputDevice(Id)
|
||||
InputDeviceMotion::InputDeviceMotion(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_allChannelsById()
|
||||
, m_accelerationChannelsById()
|
||||
, m_rotationRateChannelsById()
|
||||
@@ -107,8 +108,8 @@ namespace AzFramework
|
||||
m_orientationChannelsById[channelId] = channel;
|
||||
}
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
|
||||
// Connect to the motion sensor request bus
|
||||
InputMotionSensorRequestBus::Handler::BusConnect(GetInputDeviceId());
|
||||
|
||||
@@ -126,9 +126,20 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceMotion&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
InputDeviceMotion();
|
||||
//! \param[in] inputDeviceId Optional override of the default input device id
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceMotion(const InputDeviceId& inputDeviceId = Id,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
|
||||
@@ -67,8 +67,9 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceMouse::InputDeviceMouse(AzFramework::InputDeviceId id)
|
||||
: InputDevice(id)
|
||||
InputDeviceMouse::InputDeviceMouse(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_allChannelsById()
|
||||
, m_buttonChannelsById()
|
||||
, m_movementChannelsById()
|
||||
@@ -97,8 +98,8 @@ namespace AzFramework
|
||||
m_cursorPositionChannel = aznew InputChannelDeltaWithSharedPosition2D(SystemCursorPosition, *this, m_cursorPositionData2D);
|
||||
m_allChannelsById[SystemCursorPosition] = m_cursorPositionChannel;
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
|
||||
// Connect to the system cursor request bus
|
||||
InputSystemCursorRequestBus::Handler::BusConnect(GetInputDeviceId());
|
||||
|
||||
@@ -122,9 +122,20 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceMouse&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
explicit InputDeviceMouse(AzFramework::InputDeviceId id = Id);
|
||||
//! \param[in] inputDeviceId Optional override of the default input device id
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceMouse(const InputDeviceId& inputDeviceId = Id,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
|
||||
@@ -59,8 +59,9 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceTouch::InputDeviceTouch()
|
||||
: InputDevice(Id)
|
||||
InputDeviceTouch::InputDeviceTouch(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_allChannelsById()
|
||||
, m_touchChannelsById()
|
||||
, m_pimpl(nullptr)
|
||||
@@ -75,8 +76,8 @@ namespace AzFramework
|
||||
m_touchChannelsById[channelId] = channel;
|
||||
}
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -77,9 +77,20 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceTouch&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
InputDeviceTouch();
|
||||
//! \param[in] inputDeviceId Optional override of the default input device id
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceTouch(const InputDeviceId& inputDeviceId = Id,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
|
||||
+5
-4
@@ -51,8 +51,9 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
InputDeviceVirtualKeyboard::InputDeviceVirtualKeyboard()
|
||||
: InputDevice(Id)
|
||||
InputDeviceVirtualKeyboard::InputDeviceVirtualKeyboard(const InputDeviceId& inputDeviceId,
|
||||
ImplementationFactory implementationFactory)
|
||||
: InputDevice(inputDeviceId)
|
||||
, m_allChannelsById()
|
||||
, m_pimpl()
|
||||
, m_implementationRequestHandler(*this)
|
||||
@@ -65,8 +66,8 @@ namespace AzFramework
|
||||
m_commandChannelsById[channelId] = channel;
|
||||
}
|
||||
|
||||
// Create the platform specific implementation
|
||||
m_pimpl.reset(Implementation::Create(*this));
|
||||
// Create the platform specific or custom implementation
|
||||
m_pimpl.reset(implementationFactory ? implementationFactory(*this) : nullptr);
|
||||
|
||||
// Connect to the text entry request bus
|
||||
InputTextEntryRequestBus::Handler::BusConnect(GetInputDeviceId());
|
||||
|
||||
+12
-1
@@ -69,9 +69,20 @@ namespace AzFramework
|
||||
// Reflection
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Foward declare the internal Implementation class so it can be passed into the constructor
|
||||
class Implementation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Alias for the function type used to create a custom implementation for this input device
|
||||
using ImplementationFactory = Implementation*(InputDeviceVirtualKeyboard&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
InputDeviceVirtualKeyboard();
|
||||
//! \param[in] inputDeviceId Optional override of the default input device id
|
||||
//! \param[in] implementationFactory Optional override of the default Implementation::Create
|
||||
explicit InputDeviceVirtualKeyboard(const InputDeviceId& inputDeviceId = Id,
|
||||
ImplementationFactory implementationFactory = &Implementation::Create);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Disable copying
|
||||
|
||||
@@ -24,17 +24,17 @@ namespace AzFramework
|
||||
IMatchmakingRequests() = default;
|
||||
virtual ~IMatchmakingRequests() = default;
|
||||
|
||||
// Registers a player's acceptance or rejection of a proposed matchmaking.
|
||||
// @param acceptMatchRequest The request of AcceptMatch operation
|
||||
//! Registers a player's acceptance or rejection of a proposed matchmaking.
|
||||
//! @param acceptMatchRequest The request of AcceptMatch operation
|
||||
virtual void AcceptMatch(const AcceptMatchRequest& acceptMatchRequest) = 0;
|
||||
|
||||
// Create a game match for a group of players.
|
||||
// @param startMatchmakingRequest The request of StartMatchmaking operation
|
||||
// @return A unique identifier for a matchmaking ticket
|
||||
//! Create a game match for a group of players.
|
||||
//! @param startMatchmakingRequest The request of StartMatchmaking operation
|
||||
//! @return A unique identifier for a matchmaking ticket
|
||||
virtual AZStd::string StartMatchmaking(const StartMatchmakingRequest& startMatchmakingRequest) = 0;
|
||||
|
||||
// Cancels a matchmaking ticket that is currently being processed.
|
||||
// @param stopMatchmakingRequest The request of StopMatchmaking operation
|
||||
//! Cancels a matchmaking ticket that is currently being processed.
|
||||
//! @param stopMatchmakingRequest The request of StopMatchmaking operation
|
||||
virtual void StopMatchmaking(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
|
||||
};
|
||||
|
||||
@@ -48,16 +48,16 @@ namespace AzFramework
|
||||
IMatchmakingAsyncRequests() = default;
|
||||
virtual ~IMatchmakingAsyncRequests() = default;
|
||||
|
||||
// AcceptMatch Async
|
||||
// @param acceptMatchRequest The request of AcceptMatch operation
|
||||
//! AcceptMatch Async
|
||||
//! @param acceptMatchRequest The request of AcceptMatch operation
|
||||
virtual void AcceptMatchAsync(const AcceptMatchRequest& acceptMatchRequest) = 0;
|
||||
|
||||
// StartMatchmaking Async
|
||||
// @param startMatchmakingRequest The request of StartMatchmaking operation
|
||||
//! StartMatchmaking Async
|
||||
//! @param startMatchmakingRequest The request of StartMatchmaking operation
|
||||
virtual void StartMatchmakingAsync(const StartMatchmakingRequest& startMatchmakingRequest) = 0;
|
||||
|
||||
// StopMatchmaking Async
|
||||
// @param stopMatchmakingRequest The request of StopMatchmaking operation
|
||||
//! StopMatchmaking Async
|
||||
//! @param stopMatchmakingRequest The request of StopMatchmaking operation
|
||||
virtual void StopMatchmakingAsync(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
|
||||
};
|
||||
|
||||
@@ -76,14 +76,14 @@ namespace AzFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
|
||||
//! OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
|
||||
virtual void OnAcceptMatchAsyncComplete() = 0;
|
||||
|
||||
// OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
|
||||
// @param matchmakingTicketId The unique identifier for the matchmaking ticket
|
||||
//! OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
|
||||
//! @param matchmakingTicketId The unique identifier for the matchmaking ticket
|
||||
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
|
||||
|
||||
// OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
|
||||
//! OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
|
||||
virtual void OnStopMatchmakingAsyncComplete() = 0;
|
||||
};
|
||||
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
|
||||
|
||||
@@ -29,17 +29,17 @@ namespace AzFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnMatchAcceptance is fired when match is found and pending on acceptance
|
||||
// Use this notification to accept found match
|
||||
//! OnMatchAcceptance is fired when match is found and pending on acceptance
|
||||
//! Use this notification to accept found match
|
||||
virtual void OnMatchAcceptance() = 0;
|
||||
|
||||
// OnMatchComplete is fired when match is complete
|
||||
//! OnMatchComplete is fired when match is complete
|
||||
virtual void OnMatchComplete() = 0;
|
||||
|
||||
// OnMatchError is fired when match is processed with error
|
||||
//! OnMatchError is fired when match is processed with error
|
||||
virtual void OnMatchError() = 0;
|
||||
|
||||
// OnMatchFailure is fired when match is failed to complete
|
||||
//! OnMatchFailure is fired when match is failed to complete
|
||||
virtual void OnMatchFailure() = 0;
|
||||
};
|
||||
using MatchmakingNotificationBus = AZ::EBus<MatchmakingNotifications>;
|
||||
|
||||
@@ -29,11 +29,11 @@ namespace AzFramework
|
||||
AcceptMatchRequest() = default;
|
||||
virtual ~AcceptMatchRequest() = default;
|
||||
|
||||
// Player response to accept or reject match
|
||||
//! Player response to accept or reject match
|
||||
bool m_acceptMatch;
|
||||
// A list of unique identifiers for players delivering the response
|
||||
//! A list of unique identifiers for players delivering the response
|
||||
AZStd::vector<AZStd::string> m_playerIds;
|
||||
// A unique identifier for a matchmaking ticket
|
||||
//! A unique identifier for a matchmaking ticket
|
||||
AZStd::string m_ticketId;
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AzFramework
|
||||
StartMatchmakingRequest() = default;
|
||||
virtual ~StartMatchmakingRequest() = default;
|
||||
|
||||
// A unique identifier for a matchmaking ticket
|
||||
//! A unique identifier for a matchmaking ticket
|
||||
AZStd::string m_ticketId;
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace AzFramework
|
||||
StopMatchmakingRequest() = default;
|
||||
virtual ~StopMatchmakingRequest() = default;
|
||||
|
||||
// A unique identifier for a matchmaking ticket
|
||||
//! A unique identifier for a matchmaking ticket
|
||||
AZStd::string m_ticketId;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
+67
-1
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
namespace AzPhysics
|
||||
{
|
||||
@@ -28,6 +29,71 @@ namespace AzPhysics
|
||||
->Field("ChildLocalPosition", &JointConfiguration::m_childLocalPosition)
|
||||
->Field("StartSimulationEnabled", &JointConfiguration::m_startSimulationEnabled)
|
||||
;
|
||||
|
||||
if (auto* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<JointConfiguration>("Joint Configuration", "Joint configuration.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_parentLocalRotation,
|
||||
"Parent local rotation", "Parent joint frame relative to parent body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetParentLocalRotationVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_parentLocalPosition,
|
||||
"Parent local position", "Joint position relative to parent body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetParentLocalPositionVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_childLocalRotation,
|
||||
"Child local rotation", "Child joint frame relative to child body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetChildLocalRotationVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_childLocalPosition,
|
||||
"Child local position", "Joint position relative to child body.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetChildLocalPositionVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JointConfiguration::m_startSimulationEnabled,
|
||||
"Start simulation enabled", "When active, the joint will be enabled when the simulation begins.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &JointConfiguration::GetStartSimulationEnabledVisibility)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetPropertyVisibility(JointConfiguration::PropertyVisibility property) const
|
||||
{
|
||||
return (m_propertyVisibilityFlags & property) != 0 ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
|
||||
}
|
||||
|
||||
void JointConfiguration::SetPropertyVisibility(JointConfiguration::PropertyVisibility property, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
m_propertyVisibilityFlags |= property;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_propertyVisibilityFlags &= ~property;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetParentLocalRotationVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ParentLocalRotation);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetParentLocalPositionVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ParentLocalPosition);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetChildLocalRotationVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ChildLocalRotation);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetChildLocalPositionVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::ChildLocalPosition);
|
||||
}
|
||||
|
||||
AZ::Crc32 JointConfiguration::GetStartSimulationEnabledVisibility() const
|
||||
{
|
||||
return GetPropertyVisibility(JointConfiguration::PropertyVisibility::StartSimulationEnabled);
|
||||
}
|
||||
} // namespace AzPhysics
|
||||
|
||||
@@ -31,6 +31,25 @@ namespace AzPhysics
|
||||
JointConfiguration() = default;
|
||||
virtual ~JointConfiguration() = default;
|
||||
|
||||
// Visibility helpers for use in the Editor when reflected.
|
||||
enum PropertyVisibility : AZ::u8
|
||||
{
|
||||
ParentLocalRotation = 1 << 0, //!< Whether the parent local rotation is visible.
|
||||
ParentLocalPosition = 1 << 1, //!< Whether the parent local position is visible.
|
||||
ChildLocalRotation = 1 << 2, //!< Whether the child local rotation is visible.
|
||||
ChildLocalPosition = 1 << 3, //!< Whether the child local position is visible.
|
||||
StartSimulationEnabled = 1 << 4 //!< Whether the start simulation enabled setting is visible.
|
||||
};
|
||||
|
||||
AZ::Crc32 GetPropertyVisibility(PropertyVisibility property) const;
|
||||
void SetPropertyVisibility(PropertyVisibility property, bool isVisible);
|
||||
|
||||
AZ::Crc32 GetParentLocalRotationVisibility() const;
|
||||
AZ::Crc32 GetParentLocalPositionVisibility() const;
|
||||
AZ::Crc32 GetChildLocalRotationVisibility() const;
|
||||
AZ::Crc32 GetChildLocalPositionVisibility() const;
|
||||
AZ::Crc32 GetStartSimulationEnabledVisibility() const;
|
||||
|
||||
// Entity/object association.
|
||||
void* m_customUserData = nullptr;
|
||||
|
||||
@@ -40,8 +59,11 @@ namespace AzPhysics
|
||||
AZ::Quaternion m_childLocalRotation = AZ::Quaternion::CreateIdentity(); ///< Child joint frame relative to child body.
|
||||
AZ::Vector3 m_childLocalPosition = AZ::Vector3::CreateZero(); ///< Joint position relative to child body.
|
||||
bool m_startSimulationEnabled = true;
|
||||
|
||||
|
||||
// For debugging/tracking purposes only.
|
||||
AZStd::string m_debugName;
|
||||
|
||||
// Default all visibility settings to invisible, since most joint configurations don't need to display these.
|
||||
AZ::u8 m_propertyVisibilityFlags = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@ namespace AzFramework
|
||||
//! The properties for handling join session request.
|
||||
struct SessionConnectionConfig
|
||||
{
|
||||
// A unique identifier for registered player in session.
|
||||
//! A unique identifier for registered player in session.
|
||||
AZStd::string m_playerSessionId;
|
||||
|
||||
// The DNS identifier assigned to the instance that is running the session.
|
||||
//! The DNS identifier assigned to the instance that is running the session.
|
||||
AZStd::string m_dnsName;
|
||||
|
||||
// The IP address of the session.
|
||||
//! The IP address of the session.
|
||||
AZStd::string m_ipAddress;
|
||||
|
||||
// The port number for the session.
|
||||
//! The port number for the session.
|
||||
uint16_t m_port = 0;
|
||||
};
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace AzFramework
|
||||
//! The properties for handling player connect/disconnect
|
||||
struct PlayerConnectionConfig
|
||||
{
|
||||
// A unique identifier for player connection.
|
||||
//! A unique identifier for player connection.
|
||||
uint32_t m_playerConnectionId = 0;
|
||||
|
||||
// A unique identifier for registered player in session.
|
||||
//! A unique identifier for registered player in session.
|
||||
AZStd::string m_playerSessionId;
|
||||
};
|
||||
|
||||
@@ -51,12 +51,12 @@ namespace AzFramework
|
||||
ISessionHandlingClientRequests() = default;
|
||||
virtual ~ISessionHandlingClientRequests() = default;
|
||||
|
||||
// Request the player join session
|
||||
// @param sessionConnectionConfig The required properties to handle the player join session process
|
||||
// @return The result of player join session process
|
||||
//! Request the player join session
|
||||
//! @param sessionConnectionConfig The required properties to handle the player join session process
|
||||
//! @return The result of player join session process
|
||||
virtual bool RequestPlayerJoinSession(const SessionConnectionConfig& sessionConnectionConfig) = 0;
|
||||
|
||||
// Request the connected player leave session
|
||||
//! Request the connected player leave session
|
||||
virtual void RequestPlayerLeaveSession() = 0;
|
||||
};
|
||||
|
||||
@@ -69,26 +69,26 @@ namespace AzFramework
|
||||
ISessionHandlingProviderRequests() = default;
|
||||
virtual ~ISessionHandlingProviderRequests() = default;
|
||||
|
||||
// Handle the destroy session process
|
||||
//! Handle the destroy session process
|
||||
virtual void HandleDestroySession() = 0;
|
||||
|
||||
// Validate the player join session process
|
||||
// @param playerConnectionConfig The required properties to validate the player join session process
|
||||
// @return The result of player join session validation
|
||||
//! Validate the player join session process
|
||||
//! @param playerConnectionConfig The required properties to validate the player join session process
|
||||
//! @return The result of player join session validation
|
||||
virtual bool ValidatePlayerJoinSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
|
||||
|
||||
// Handle the player leave session process
|
||||
// @param playerConnectionConfig The required properties to handle the player leave session process
|
||||
//! Handle the player leave session process
|
||||
//! @param playerConnectionConfig The required properties to handle the player leave session process
|
||||
virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
|
||||
|
||||
// Retrieves the file location of a pem-encoded TLS certificate for Client to Server communication
|
||||
// @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
// empty string.
|
||||
//! Retrieves the file location of a pem-encoded TLS certificate for Client to Server communication
|
||||
//! @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
//! empty string.
|
||||
virtual AZ::IO::Path GetExternalSessionCertificate() = 0;
|
||||
|
||||
// Retrieves the file location of a pem-encoded TLS certificate for Server to Server communication
|
||||
// @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
// empty string.
|
||||
//! Retrieves the file location of a pem-encoded TLS certificate for Server to Server communication
|
||||
//! @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
//! empty string.
|
||||
virtual AZ::IO::Path GetInternalSessionCertificate() = 0;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -25,22 +25,22 @@ namespace AzFramework
|
||||
ISessionRequests() = default;
|
||||
virtual ~ISessionRequests() = default;
|
||||
|
||||
// Create a session for players to find and join.
|
||||
// @param createSessionRequest The request of CreateSession operation
|
||||
// @return The request id if session creation request succeeds; empty if it fails
|
||||
//! Create a session for players to find and join.
|
||||
//! @param createSessionRequest The request of CreateSession operation
|
||||
//! @return The request id if session creation request succeeds; empty if it fails
|
||||
virtual AZStd::string CreateSession(const CreateSessionRequest& createSessionRequest) = 0;
|
||||
|
||||
// Retrieve all active sessions that match the given search criteria and sorted in specific order.
|
||||
// @param searchSessionsRequest The request of SearchSessions operation
|
||||
// @return The response of SearchSessions operation
|
||||
//! Retrieve all active sessions that match the given search criteria and sorted in specific order.
|
||||
//! @param searchSessionsRequest The request of SearchSessions operation
|
||||
//! @return The response of SearchSessions operation
|
||||
virtual SearchSessionsResponse SearchSessions(const SearchSessionsRequest& searchSessionsRequest) const = 0;
|
||||
|
||||
// Reserve an open player slot in a session, and perform connection from client to server.
|
||||
// @param joinSessionRequest The request of JoinSession operation
|
||||
// @return True if joining session succeeds; False otherwise
|
||||
//! Reserve an open player slot in a session, and perform connection from client to server.
|
||||
//! @param joinSessionRequest The request of JoinSession operation
|
||||
//! @return True if joining session succeeds; False otherwise
|
||||
virtual bool JoinSession(const JoinSessionRequest& joinSessionRequest) = 0;
|
||||
|
||||
// Disconnect player from session.
|
||||
//! Disconnect player from session.
|
||||
virtual void LeaveSession() = 0;
|
||||
};
|
||||
|
||||
@@ -54,19 +54,19 @@ namespace AzFramework
|
||||
ISessionAsyncRequests() = default;
|
||||
virtual ~ISessionAsyncRequests() = default;
|
||||
|
||||
// CreateSession Async
|
||||
// @param createSessionRequest The request of CreateSession operation
|
||||
//! CreateSession Async
|
||||
//! @param createSessionRequest The request of CreateSession operation
|
||||
virtual void CreateSessionAsync(const CreateSessionRequest& createSessionRequest) = 0;
|
||||
|
||||
// SearchSessions Async
|
||||
// @param searchSessionsRequest The request of SearchSessions operation
|
||||
//! SearchSessions Async
|
||||
//! @param searchSessionsRequest The request of SearchSessions operation
|
||||
virtual void SearchSessionsAsync(const SearchSessionsRequest& searchSessionsRequest) const = 0;
|
||||
|
||||
// JoinSession Async
|
||||
// @param joinSessionRequest The request of JoinSession operation
|
||||
//! JoinSession Async
|
||||
//! @param joinSessionRequest The request of JoinSession operation
|
||||
virtual void JoinSessionAsync(const JoinSessionRequest& joinSessionRequest) = 0;
|
||||
|
||||
// LeaveSession Async
|
||||
//! LeaveSession Async
|
||||
virtual void LeaveSessionAsync() = 0;
|
||||
};
|
||||
|
||||
@@ -85,19 +85,19 @@ namespace AzFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes
|
||||
// @param createSessionResponse The request id if session creation request succeeds; empty if it fails
|
||||
//! OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes
|
||||
//! @param createSessionResponse The request id if session creation request succeeds; empty if it fails
|
||||
virtual void OnCreateSessionAsyncComplete(const AZStd::string& createSessionReponse) = 0;
|
||||
|
||||
// OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes
|
||||
// @param searchSessionsResponse The response of SearchSessions call
|
||||
//! OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes
|
||||
//! @param searchSessionsResponse The response of SearchSessions call
|
||||
virtual void OnSearchSessionsAsyncComplete(const SearchSessionsResponse& searchSessionsResponse) = 0;
|
||||
|
||||
// OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes
|
||||
// @param joinSessionsResponse True if joining session succeeds; False otherwise
|
||||
//! OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes
|
||||
//! @param joinSessionsResponse True if joining session succeeds; False otherwise
|
||||
virtual void OnJoinSessionAsyncComplete(bool joinSessionsResponse) = 0;
|
||||
|
||||
// OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes
|
||||
//! OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes
|
||||
virtual void OnLeaveSessionAsyncComplete() = 0;
|
||||
};
|
||||
using SessionAsyncRequestNotificationBus = AZ::EBus<SessionAsyncRequestNotifications>;
|
||||
|
||||
@@ -24,46 +24,46 @@ namespace AzFramework
|
||||
SessionConfig() = default;
|
||||
virtual ~SessionConfig() = default;
|
||||
|
||||
// A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
|
||||
//! A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
|
||||
uint64_t m_creationTime = 0;
|
||||
|
||||
// A time stamp indicating when this data object was terminated. Same format as creation time.
|
||||
//! A time stamp indicating when this data object was terminated. Same format as creation time.
|
||||
uint64_t m_terminationTime = 0;
|
||||
|
||||
// A unique identifier for a player or entity creating the session.
|
||||
//! A unique identifier for a player or entity creating the session.
|
||||
AZStd::string m_creatorId;
|
||||
|
||||
// A collection of custom properties for a session.
|
||||
//! A collection of custom properties for a session.
|
||||
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
|
||||
|
||||
// The matchmaking process information that was used to create the session.
|
||||
//! The matchmaking process information that was used to create the session.
|
||||
AZStd::string m_matchmakingData;
|
||||
|
||||
// A unique identifier for the session.
|
||||
//! A unique identifier for the session.
|
||||
AZStd::string m_sessionId;
|
||||
|
||||
// A descriptive label that is associated with a session.
|
||||
//! A descriptive label that is associated with a session.
|
||||
AZStd::string m_sessionName;
|
||||
|
||||
// The DNS identifier assigned to the instance that is running the session.
|
||||
//! The DNS identifier assigned to the instance that is running the session.
|
||||
AZStd::string m_dnsName;
|
||||
|
||||
// The IP address of the session.
|
||||
//! The IP address of the session.
|
||||
AZStd::string m_ipAddress;
|
||||
|
||||
// The port number for the session.
|
||||
//! The port number for the session.
|
||||
uint16_t m_port = 0;
|
||||
|
||||
// The maximum number of players that can be connected simultaneously to the session.
|
||||
//! The maximum number of players that can be connected simultaneously to the session.
|
||||
uint64_t m_maxPlayer = 0;
|
||||
|
||||
// Number of players currently in the session.
|
||||
//! Number of players currently in the session.
|
||||
uint64_t m_currentPlayer = 0;
|
||||
|
||||
// Current status of the session.
|
||||
//! Current status of the session.
|
||||
AZStd::string m_status;
|
||||
|
||||
// Provides additional information about session status.
|
||||
//! Provides additional information about session status.
|
||||
AZStd::string m_statusReason;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -29,42 +29,42 @@ namespace AzFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnSessionHealthCheck is fired in health check process
|
||||
// Use this notification to perform any custom health check
|
||||
// @return True if OnSessionHealthCheck succeeds, false otherwise
|
||||
//! OnSessionHealthCheck is fired in health check process
|
||||
//! Use this notification to perform any custom health check
|
||||
//! @return True if OnSessionHealthCheck succeeds, false otherwise
|
||||
virtual bool OnSessionHealthCheck() = 0;
|
||||
|
||||
// OnCreateSessionBegin is fired at the beginning of session creation process
|
||||
// Use this notification to perform any necessary configuration or initialization before
|
||||
// creating session
|
||||
// @param sessionConfig The properties to describe a session
|
||||
// @return True if OnCreateSessionBegin succeeds, false otherwise
|
||||
//! OnCreateSessionBegin is fired at the beginning of session creation process
|
||||
//! Use this notification to perform any necessary configuration or initialization before
|
||||
//! creating session
|
||||
//! @param sessionConfig The properties to describe a session
|
||||
//! @return True if OnCreateSessionBegin succeeds, false otherwise
|
||||
virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0;
|
||||
|
||||
// OnCreateSessionEnd is fired at the end of session creation process
|
||||
// Use this notification to perform any follow-up operation after session is created and active
|
||||
//! OnCreateSessionEnd is fired at the end of session creation process
|
||||
//! Use this notification to perform any follow-up operation after session is created and active
|
||||
virtual void OnCreateSessionEnd() = 0;
|
||||
|
||||
// OnDestroySessionBegin is fired at the beginning of session termination process
|
||||
// Use this notification to perform any cleanup operation before destroying session,
|
||||
// like gracefully disconnect players, cleanup data, etc.
|
||||
// @return True if OnDestroySessionBegin succeeds, false otherwise
|
||||
//! OnDestroySessionBegin is fired at the beginning of session termination process
|
||||
//! Use this notification to perform any cleanup operation before destroying session,
|
||||
//! like gracefully disconnect players, cleanup data, etc.
|
||||
//! @return True if OnDestroySessionBegin succeeds, false otherwise
|
||||
virtual bool OnDestroySessionBegin() = 0;
|
||||
|
||||
// OnDestroySessionEnd is fired at the end of session termination process
|
||||
// Use this notification to perform any follow-up operation after session is destroyed,
|
||||
// like shutdown application process, etc.
|
||||
//! OnDestroySessionEnd is fired at the end of session termination process
|
||||
//! Use this notification to perform any follow-up operation after session is destroyed,
|
||||
//! like shutdown application process, etc.
|
||||
virtual void OnDestroySessionEnd() = 0;
|
||||
|
||||
// OnUpdateSessionBegin is fired at the beginning of session update process
|
||||
// Use this notification to perform any configuration or initialization to handle
|
||||
// the session settings changing
|
||||
// @param sessionConfig The properties to describe a session
|
||||
// @param updateReason The reason for session update
|
||||
//! OnUpdateSessionBegin is fired at the beginning of session update process
|
||||
//! Use this notification to perform any configuration or initialization to handle
|
||||
//! the session settings changing
|
||||
//! @param sessionConfig The properties to describe a session
|
||||
//! @param updateReason The reason for session update
|
||||
virtual void OnUpdateSessionBegin(const SessionConfig& sessionConfig, const AZStd::string& updateReason) = 0;
|
||||
|
||||
// OnUpdateSessionBegin is fired at the end of session update process
|
||||
// Use this notification to perform any follow-up operations after session is updated
|
||||
//! OnUpdateSessionBegin is fired at the end of session update process
|
||||
//! Use this notification to perform any follow-up operations after session is updated
|
||||
virtual void OnUpdateSessionEnd() = 0;
|
||||
};
|
||||
using SessionNotificationBus = AZ::EBus<SessionNotifications>;
|
||||
|
||||
@@ -31,16 +31,16 @@ namespace AzFramework
|
||||
CreateSessionRequest() = default;
|
||||
virtual ~CreateSessionRequest() = default;
|
||||
|
||||
// A unique identifier for a player or entity creating the session.
|
||||
//! A unique identifier for a player or entity creating the session.
|
||||
AZStd::string m_creatorId;
|
||||
|
||||
// A collection of custom properties for a session.
|
||||
//! A collection of custom properties for a session.
|
||||
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
|
||||
|
||||
// A descriptive label that is associated with a session.
|
||||
//! A descriptive label that is associated with a session.
|
||||
AZStd::string m_sessionName;
|
||||
|
||||
// The maximum number of players that can be connected simultaneously to the session.
|
||||
//! The maximum number of players that can be connected simultaneously to the session.
|
||||
uint64_t m_maxPlayer = 0;
|
||||
};
|
||||
|
||||
@@ -54,17 +54,17 @@ namespace AzFramework
|
||||
SearchSessionsRequest() = default;
|
||||
virtual ~SearchSessionsRequest() = default;
|
||||
|
||||
// String containing the search criteria for the session search. If no filter expression is included, the request returns results
|
||||
// for all active sessions.
|
||||
//! String containing the search criteria for the session search. If no filter expression is included, the request returns results
|
||||
//! for all active sessions.
|
||||
AZStd::string m_filterExpression;
|
||||
|
||||
// Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order.
|
||||
//! Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order.
|
||||
AZStd::string m_sortExpression;
|
||||
|
||||
// The maximum number of results to return.
|
||||
//! The maximum number of results to return.
|
||||
uint8_t m_maxResult = 0;
|
||||
|
||||
// A token that indicates the start of the next sequential page of results.
|
||||
//! A token that indicates the start of the next sequential page of results.
|
||||
AZStd::string m_nextToken;
|
||||
};
|
||||
|
||||
@@ -78,10 +78,10 @@ namespace AzFramework
|
||||
SearchSessionsResponse() = default;
|
||||
virtual ~SearchSessionsResponse() = default;
|
||||
|
||||
// A collection of sessions that match the search criteria and sorted in specific order.
|
||||
//! A collection of sessions that match the search criteria and sorted in specific order.
|
||||
AZStd::vector<SessionConfig> m_sessionConfigs;
|
||||
|
||||
// A token that indicates the start of the next sequential page of results.
|
||||
//! A token that indicates the start of the next sequential page of results.
|
||||
AZStd::string m_nextToken;
|
||||
};
|
||||
|
||||
@@ -95,13 +95,13 @@ namespace AzFramework
|
||||
JoinSessionRequest() = default;
|
||||
virtual ~JoinSessionRequest() = default;
|
||||
|
||||
// A unique identifier for the session.
|
||||
//! A unique identifier for the session.
|
||||
AZStd::string m_sessionId;
|
||||
|
||||
// A unique identifier for a player. Player IDs are developer-defined.
|
||||
//! A unique identifier for a player. Player IDs are developer-defined.
|
||||
AZStd::string m_playerId;
|
||||
|
||||
// Developer-defined information related to a player.
|
||||
//! Developer-defined information related to a player.
|
||||
AZStd::string m_playerData;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -258,10 +258,17 @@ namespace AzFramework
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void XcbNativeWindow::SetWindowTitle(const AZStd::string& title)
|
||||
{
|
||||
// Set the title of both the window and the task bar by using
|
||||
// a buffer to hold the title twice, separated by a null-terminator
|
||||
auto doubleTitleSize = (title.size() + 1) * 2;
|
||||
AZStd::string doubleTitle(doubleTitleSize, '\0');
|
||||
azstrncpy(doubleTitle.data(), doubleTitleSize, title.c_str(), title.size());
|
||||
azstrncpy(&doubleTitle.data()[title.size() + 1], title.size(), title.c_str(), title.size());
|
||||
|
||||
xcb_void_cookie_t xcbCheckResult;
|
||||
xcbCheckResult = xcb_change_property(
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, static_cast<uint32_t>(title.size()),
|
||||
title.c_str());
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, static_cast<uint32_t>(doubleTitle.size()),
|
||||
doubleTitle.c_str());
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set window title.");
|
||||
}
|
||||
|
||||
|
||||
+19
-13
@@ -10,6 +10,8 @@
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -24,14 +26,20 @@ namespace AzFramework::AssetSystem::Platform
|
||||
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
|
||||
// In Mac the Editor and game is within a bundle, so the path to the sibling app
|
||||
// has to go up from the Contents/MacOS folder the binary is in
|
||||
assetProcessorPath /= "../../../AssetProcessor.app";
|
||||
assetProcessorPath /= "../../../AssetProcessor.app/Contents/MacOS/AssetProcessor";
|
||||
assetProcessorPath = assetProcessorPath.LexicallyNormal();
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
|
||||
{
|
||||
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
|
||||
assetProcessorPath =
|
||||
AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_TRAIT_OS_PLATFORM_NAME / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.app";
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if (AZ::IO::FixedMaxPath installedBinariesPath;
|
||||
settingsRegistry->Get(installedBinariesPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder))
|
||||
{
|
||||
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
|
||||
assetProcessorPath = AZ::IO::FixedMaxPath{ engineRoot } / installedBinariesPath / "AssetProcessor.app/Contents/MacOS/AssetProcessor";
|
||||
}
|
||||
}
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
|
||||
{
|
||||
@@ -39,23 +47,21 @@ namespace AzFramework::AssetSystem::Platform
|
||||
}
|
||||
}
|
||||
|
||||
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"(open -g "%s" --args --start-hidden)", assetProcessorPath.c_str());
|
||||
AZStd::string commandLineParams;
|
||||
// Add the engine path to the launch command if not empty
|
||||
if (!engineRoot.empty())
|
||||
{
|
||||
fullLaunchCommand += R"( --engine-path=")";
|
||||
fullLaunchCommand += engineRoot;
|
||||
fullLaunchCommand += '"';
|
||||
commandLineParams += AZStd::string::format("\"--engine-path=\"%s\"\"", engineRoot.data());
|
||||
}
|
||||
|
||||
// Add the active project path to the launch command if not empty
|
||||
if (!projectPath.empty())
|
||||
{
|
||||
fullLaunchCommand += R"( --project-path=")";
|
||||
fullLaunchCommand += projectPath;
|
||||
fullLaunchCommand += '"';
|
||||
commandLineParams += AZStd::string::format(" \"--regset=/Amazon/AzCore/Bootstrap/project_path=\"%s\"\"", projectPath.data());
|
||||
}
|
||||
|
||||
return system(fullLaunchCommand.c_str()) == 0;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
processLaunchInfo.m_processExecutableString = AZStd::move(assetProcessorPath.Native());
|
||||
processLaunchInfo.m_commandlineParameters = commandLineParams;
|
||||
return AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -54,6 +54,7 @@ namespace AzFramework
|
||||
RECT m_windowRectToRestoreOnFullScreenExit; //!< The position and size of the window to restore when exiting full screen.
|
||||
UINT m_windowStyleToRestoreOnFullScreenExit; //!< The style(s) of the window to restore when exiting full screen.
|
||||
bool m_isInBorderlessWindowFullScreenState = false; //!< Was a borderless window used to enter full screen state?
|
||||
bool m_shouldEnterFullScreenStateOnActivate = false; //!< Should we enter full screen state when the window is activated?
|
||||
|
||||
using GetDpiForWindowType = UINT(HWND hwnd);
|
||||
GetDpiForWindowType* m_getDpiFunction = nullptr;
|
||||
@@ -249,6 +250,28 @@ namespace AzFramework
|
||||
AzFramework::RawInputNotificationBusWindows::Broadcast(&AzFramework::RawInputNotificationsWindows::OnRawInputCodeUnitUTF16Event, codeUnitUTF16);
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
// Alt-tabbing out of the app while it is in a full screen state does not
|
||||
// work unless we explicitly exit the full screen state upon deactivation,
|
||||
// in which case we want to enter full screen state again upon activation.
|
||||
const bool windowIsNowInactive = (LOWORD(wParam) == WA_INACTIVE);
|
||||
const bool windowFullScreenState = nativeWindowImpl->GetFullScreenState();
|
||||
if (windowIsNowInactive &&
|
||||
windowFullScreenState)
|
||||
{
|
||||
nativeWindowImpl->m_shouldEnterFullScreenStateOnActivate = true;
|
||||
nativeWindowImpl->SetFullScreenState(false);
|
||||
}
|
||||
else if (!windowIsNowInactive &&
|
||||
!windowFullScreenState &&
|
||||
nativeWindowImpl->m_shouldEnterFullScreenStateOnActivate)
|
||||
{
|
||||
nativeWindowImpl->m_shouldEnterFullScreenStateOnActivate = false;
|
||||
nativeWindowImpl->SetFullScreenState(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
// Handle ALT+ENTER to toggle full screen unless exclsuive full screen
|
||||
|
||||
@@ -308,7 +308,9 @@ namespace UnitTest
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_app->Start(desc);
|
||||
AZ::ComponentApplication::StartupParameters startupParameters;
|
||||
startupParameters.m_loadAssetCatalog = false;
|
||||
m_app->Start(desc, startupParameters);
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
|
||||
@@ -45,6 +45,13 @@ namespace AzGameFramework
|
||||
enginePakPath = AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "engine.pak";
|
||||
m_archive->OpenPack("@products@", enginePakPath.Native());
|
||||
}
|
||||
|
||||
// By default, load all archives in the products folder.
|
||||
// If you want to adjust this for your project, make sure that the archive containing
|
||||
// the bootstrap for the settings registry is still loaded here, and any archives containing
|
||||
// assets used early in startup, like default shaders, are loaded here.
|
||||
constexpr AZStd::string_view paksFolder = "@products@/*.pak"; // (@products@ assumed)
|
||||
m_archive->OpenPacks(paksFolder);
|
||||
}
|
||||
|
||||
GameApplication::~GameApplication()
|
||||
@@ -82,7 +89,7 @@ namespace AzGameFramework
|
||||
|
||||
// Used the lowercase the platform name since the bootstrap.game.<config>.<platform>.setreg is being loaded
|
||||
// from the asset cache root where all the files are in lowercased from regardless of the filesystem case-sensitivity
|
||||
static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE "." AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER ".setreg";
|
||||
static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE ".setreg";
|
||||
|
||||
AZ::IO::FixedMaxPath cacheRootPath;
|
||||
if (registry.Get(cacheRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace AzQtComponents
|
||||
, m_closeOnClick(true)
|
||||
, m_ui(new Ui::ToastNotification())
|
||||
, m_fadeAnimation(nullptr)
|
||||
, m_configuration(toastConfiguration)
|
||||
{
|
||||
setProperty("HasNoWindowDecorations", true);
|
||||
|
||||
setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
m_borderRadius = toastConfiguration.m_borderRadius;
|
||||
if (m_borderRadius > 0)
|
||||
@@ -80,7 +80,13 @@ namespace AzQtComponents
|
||||
}
|
||||
|
||||
ToastNotification::~ToastNotification()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
bool ToastNotification::IsDuplicate(const ToastConfiguration& toastConfiguration)
|
||||
{
|
||||
return toastConfiguration.m_title == m_configuration.m_title
|
||||
&& toastConfiguration.m_description == m_configuration.m_description;
|
||||
}
|
||||
|
||||
void ToastNotification::paintEvent(QPaintEvent* event)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user