Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1d7294c5b | |||
| acc2346678 | |||
| 1909e5fa54 | |||
| 93358dcbeb | |||
| 0bddc1a826 | |||
| 66f0f1cf5a | |||
| c7284a781e | |||
| d7dc257927 | |||
| fc3c5fbd09 | |||
| 94ddafc7a2 | |||
| fb36145e2e | |||
| 58b6a9c1ac | |||
| 82af1e6870 | |||
| 38c8d94156 | |||
| f44697fbf4 | |||
| c019fe8946 | |||
| 105524b7c0 | |||
| 2fa10d7e6a | |||
| a60fba5bec | |||
| 7e5115114c | |||
| 197e7b95e1 | |||
| f71b134a84 | |||
| 98fa18558e | |||
| a2bb968371 | |||
| 2d13b648da | |||
| 0a1dc3c4bd | |||
| 837e532ad7 | |||
| a5b30ffc5a | |||
| 9830925309 | |||
| 0963bc0cc5 | |||
| dc538d94e5 | |||
| cbc70b4b88 | |||
| aeabf21bba | |||
| 0f07de7454 | |||
| ac6c90cd2c | |||
| 169416c2f9 | |||
| d284d908b9 | |||
| d8e5315199 | |||
| b9bbe233be | |||
| 3e728d1183 | |||
| b10c679c33 | |||
| 4f00718a38 | |||
| 07bf8fc755 | |||
| 0cc4c06213 | |||
| d31c6a2774 | |||
| b0ef83e194 | |||
| 3bca63bb71 | |||
| 40e1116e26 | |||
| 87023cae47 | |||
| 6421463df2 | |||
| 2c107c364f | |||
| d8add36212 | |||
| 499cdaae5e | |||
| 55fa33cff4 | |||
| c4ea3075cc | |||
| 8357fa34e9 | |||
| 27cc659ab9 | |||
| 66e744785f | |||
| 23267fd862 | |||
| 5db535d1dd | |||
| d9f849b03e | |||
| 1797354560 | |||
| ca5424dd7b | |||
| b44541c440 | |||
| 805bd8ef56 | |||
| 31304ee9b1 | |||
| c36d827fc5 | |||
| befd84cf0b | |||
| b4407e5044 | |||
| 42382cd8d1 | |||
| d9ee02fddf | |||
| 231aaa5bf5 | |||
| 772cb30c57 | |||
| 3f6824571f | |||
| ad8cfa5f99 | |||
| b772db5e73 | |||
| 727d1b3815 | |||
| 4342501804 | |||
| f8fdf4b306 | |||
| 4484b69036 | |||
| 015185f9d6 | |||
| e34c6e55df | |||
| b7d8c1a644 | |||
| 921f675df2 | |||
| d8e8cdba60 | |||
| 5558be2aeb | |||
| 6c1d1dc2e2 | |||
| 65814e65cc | |||
| 5cd8eb648c | |||
| 1ea245e46c | |||
| d40b9fc809 | |||
| 20147ddafb | |||
| cbbd6df0c5 | |||
| bc342df6b4 | |||
| c5cd854172 | |||
| 31c627defc | |||
| 6613030fe6 | |||
| ac03b6f50b | |||
| 667512c7ff | |||
| cd65d8a5ac | |||
| 72bfd8bdf8 | |||
| 8d096ebf61 | |||
| c5615f812c | |||
| dc8f9dc233 | |||
| 7b22bc64f3 |
@@ -3,19 +3,19 @@
|
|||||||
"AssetProcessor": {
|
"AssetProcessor": {
|
||||||
"Settings": {
|
"Settings": {
|
||||||
"Exclude PythonTest Benchmark Settings Assets": {
|
"Exclude PythonTest Benchmark Settings Assets": {
|
||||||
"pattern": ".*\\\\/PythonTests\\\\/.*benchmarksettings"
|
"pattern": "(^|.+/)PythonTests/.*benchmarksettings"
|
||||||
},
|
},
|
||||||
"Exclude fbx_tests": {
|
"Exclude fbx_tests": {
|
||||||
"pattern": ".*\\\\/fbx_tests\\\\/assets\\\\/.*"
|
"pattern": "(^|.+/)fbx_tests/assets(/.+)$"
|
||||||
},
|
},
|
||||||
"Exclude wwise_bank_dependency_tests": {
|
"Exclude wwise_bank_dependency_tests": {
|
||||||
"pattern": ".*\\\\/wwise_bank_dependency_tests\\\\/assets\\\\/.*"
|
"pattern": "(^|.+/)wwise_bank_dependency_tests/assets(/.+)$"
|
||||||
},
|
},
|
||||||
"Exclude AssetProcessorTestAssets": {
|
"Exclude AssetProcessorTestAssets": {
|
||||||
"pattern": ".*\\\\/asset_processor_tests\\\\/assets\\\\/.*"
|
"pattern": "(^|.+/)asset_processor_tests/assets(/.+)$"
|
||||||
},
|
},
|
||||||
"Exclude Restricted AssetProcessorTestAssets": {
|
"Exclude Restricted AssetProcessorTestAssets": {
|
||||||
"pattern": ".*\\\\/asset_processor_tests\\\\/restricted\\\\/.*"
|
"pattern": "(^|.+/)asset_processor_tests/restricted(/.+)$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,25 +229,35 @@ void CViewportTitleDlg::SetupHelpersButton()
|
|||||||
|
|
||||||
void CViewportTitleDlg::SetupOverflowMenu()
|
void CViewportTitleDlg::SetupOverflowMenu()
|
||||||
{
|
{
|
||||||
// Setup the overflow menu
|
// setup the overflow menu
|
||||||
QMenu* overFlowMenu = new QMenu(this);
|
auto overflowMenu = new QMenu(this);
|
||||||
|
|
||||||
m_audioMuteAction = new QAction("Mute Audio", overFlowMenu);
|
m_audioMuteAction = new QAction("Mute Audio", overflowMenu);
|
||||||
connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio);
|
connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio);
|
||||||
overFlowMenu->addAction(m_audioMuteAction);
|
overflowMenu->addAction(m_audioMuteAction);
|
||||||
|
|
||||||
m_enableVRAction = new QAction("Enable VR Preview", overFlowMenu);
|
m_enableVRAction = new QAction("Enable VR Preview", overflowMenu);
|
||||||
connect(m_enableVRAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedEnableVR);
|
connect(m_enableVRAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedEnableVR);
|
||||||
overFlowMenu->addAction(m_enableVRAction);
|
overflowMenu->addAction(m_enableVRAction);
|
||||||
|
|
||||||
overFlowMenu->addSeparator();
|
overflowMenu->addSeparator();
|
||||||
|
|
||||||
m_enableGridSnappingAction = new QAction("Enable Grid Snapping", overFlowMenu);
|
m_enableGridSnappingAction = new QAction("Enable Grid Snapping", overflowMenu);
|
||||||
connect(m_enableGridSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnGridSnappingToggled);
|
connect(m_enableGridSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnGridSnappingToggled);
|
||||||
m_enableGridSnappingAction->setCheckable(true);
|
m_enableGridSnappingAction->setCheckable(true);
|
||||||
overFlowMenu->addAction(m_enableGridSnappingAction);
|
overflowMenu->addAction(m_enableGridSnappingAction);
|
||||||
|
|
||||||
m_gridSizeActionWidget = new QWidgetAction(overFlowMenu);
|
m_enableGridVisualizationAction = new QAction("Show Grid", overflowMenu);
|
||||||
|
connect(
|
||||||
|
m_enableGridVisualizationAction, &QAction::triggered,
|
||||||
|
[]
|
||||||
|
{
|
||||||
|
SandboxEditor::SetShowingGrid(!SandboxEditor::ShowingGrid());
|
||||||
|
});
|
||||||
|
m_enableGridVisualizationAction->setCheckable(true);
|
||||||
|
overflowMenu->addAction(m_enableGridVisualizationAction);
|
||||||
|
|
||||||
|
m_gridSizeActionWidget = new QWidgetAction(overflowMenu);
|
||||||
m_gridSpinBox = new AzQtComponents::DoubleSpinBox();
|
m_gridSpinBox = new AzQtComponents::DoubleSpinBox();
|
||||||
m_gridSpinBox->setValue(SandboxEditor::GridSnappingSize());
|
m_gridSpinBox->setValue(SandboxEditor::GridSnappingSize());
|
||||||
m_gridSpinBox->setMinimum(1e-2f);
|
m_gridSpinBox->setMinimum(1e-2f);
|
||||||
@@ -257,31 +267,31 @@ void CViewportTitleDlg::SetupOverflowMenu()
|
|||||||
m_gridSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &CViewportTitleDlg::OnGridSpinBoxChanged);
|
m_gridSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &CViewportTitleDlg::OnGridSpinBoxChanged);
|
||||||
|
|
||||||
m_gridSizeActionWidget->setDefaultWidget(m_gridSpinBox);
|
m_gridSizeActionWidget->setDefaultWidget(m_gridSpinBox);
|
||||||
overFlowMenu->addAction(m_gridSizeActionWidget);
|
overflowMenu->addAction(m_gridSizeActionWidget);
|
||||||
|
|
||||||
overFlowMenu->addSeparator();
|
overflowMenu->addSeparator();
|
||||||
|
|
||||||
m_enableAngleSnappingAction = new QAction("Enable Angle Snapping", overFlowMenu);
|
m_enableAngleSnappingAction = new QAction("Enable Angle Snapping", overflowMenu);
|
||||||
connect(m_enableAngleSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnAngleSnappingToggled);
|
connect(m_enableAngleSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnAngleSnappingToggled);
|
||||||
m_enableAngleSnappingAction->setCheckable(true);
|
m_enableAngleSnappingAction->setCheckable(true);
|
||||||
overFlowMenu->addAction(m_enableAngleSnappingAction);
|
overflowMenu->addAction(m_enableAngleSnappingAction);
|
||||||
|
|
||||||
m_angleSizeActionWidget = new QWidgetAction(overFlowMenu);
|
m_angleSizeActionWidget = new QWidgetAction(overflowMenu);
|
||||||
m_angleSpinBox = new AzQtComponents::DoubleSpinBox();
|
m_angleSpinBox = new AzQtComponents::DoubleSpinBox();
|
||||||
m_angleSpinBox->setValue(SandboxEditor::AngleSnappingSize());
|
m_angleSpinBox->setValue(SandboxEditor::AngleSnappingSize());
|
||||||
m_angleSpinBox->setMinimum(1e-2f);
|
m_angleSpinBox->setMinimum(1e-2f);
|
||||||
m_angleSpinBox->setToolTip(tr("Angle Snapping"));
|
m_angleSpinBox->setToolTip(tr("Angle size"));
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
m_angleSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this,
|
m_angleSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this,
|
||||||
&CViewportTitleDlg::OnAngleSpinBoxChanged);
|
&CViewportTitleDlg::OnAngleSpinBoxChanged);
|
||||||
|
|
||||||
m_angleSizeActionWidget->setDefaultWidget(m_angleSpinBox);
|
m_angleSizeActionWidget->setDefaultWidget(m_angleSpinBox);
|
||||||
overFlowMenu->addAction(m_angleSizeActionWidget);
|
overflowMenu->addAction(m_angleSizeActionWidget);
|
||||||
|
|
||||||
m_ui->m_overflowBtn->setMenu(overFlowMenu);
|
m_ui->m_overflowBtn->setMenu(overflowMenu);
|
||||||
m_ui->m_overflowBtn->setPopupMode(QToolButton::InstantPopup);
|
m_ui->m_overflowBtn->setPopupMode(QToolButton::InstantPopup);
|
||||||
connect(overFlowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState);
|
connect(overflowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState);
|
||||||
|
|
||||||
UpdateMuteActionText();
|
UpdateMuteActionText();
|
||||||
}
|
}
|
||||||
@@ -1004,31 +1014,36 @@ void CViewportTitleDlg::OnAngleSnappingToggled()
|
|||||||
MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->trigger();
|
MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CViewportTitleDlg::OnGridSpinBoxChanged(double value)
|
void CViewportTitleDlg::OnGridSpinBoxChanged(const double value)
|
||||||
{
|
{
|
||||||
SandboxEditor::SetGridSnappingSize(static_cast<float>(value));
|
SandboxEditor::SetGridSnappingSize(aznumeric_cast<float>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CViewportTitleDlg::OnAngleSpinBoxChanged(double value)
|
void CViewportTitleDlg::OnAngleSpinBoxChanged(const double value)
|
||||||
{
|
{
|
||||||
SandboxEditor::SetAngleSnappingSize(static_cast<float>(value));
|
SandboxEditor::SetAngleSnappingSize(aznumeric_cast<float>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CViewportTitleDlg::UpdateOverFlowMenuState()
|
void CViewportTitleDlg::UpdateOverFlowMenuState()
|
||||||
{
|
{
|
||||||
bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->isChecked();
|
const bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->isChecked();
|
||||||
{
|
{
|
||||||
QSignalBlocker signalBlocker(m_enableGridSnappingAction);
|
QSignalBlocker signalBlocker(m_enableGridSnappingAction);
|
||||||
m_enableGridSnappingAction->setChecked(gridSnappingActive);
|
m_enableGridSnappingAction->setChecked(gridSnappingActive);
|
||||||
}
|
}
|
||||||
m_gridSizeActionWidget->setEnabled(gridSnappingActive);
|
m_gridSizeActionWidget->setEnabled(gridSnappingActive);
|
||||||
|
|
||||||
bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->isChecked();
|
const bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->isChecked();
|
||||||
{
|
{
|
||||||
QSignalBlocker signalBlocker(m_enableAngleSnappingAction);
|
QSignalBlocker signalBlocker(m_enableAngleSnappingAction);
|
||||||
m_enableAngleSnappingAction->setChecked(angleSnappingActive);
|
m_enableAngleSnappingAction->setChecked(angleSnappingActive);
|
||||||
}
|
}
|
||||||
m_angleSizeActionWidget->setEnabled(angleSnappingActive);
|
m_angleSizeActionWidget->setEnabled(angleSnappingActive);
|
||||||
|
|
||||||
|
{
|
||||||
|
QSignalBlocker signalBlocker(m_enableGridVisualizationAction);
|
||||||
|
m_enableGridVisualizationAction->setChecked(SandboxEditor::ShowingGrid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ protected:
|
|||||||
QAction* m_enableVRAction = nullptr;
|
QAction* m_enableVRAction = nullptr;
|
||||||
QAction* m_enableGridSnappingAction = nullptr;
|
QAction* m_enableGridSnappingAction = nullptr;
|
||||||
QAction* m_enableAngleSnappingAction = nullptr;
|
QAction* m_enableAngleSnappingAction = nullptr;
|
||||||
|
QAction* m_enableGridVisualizationAction = nullptr;
|
||||||
QComboBox* m_cameraSpeed = nullptr;
|
QComboBox* m_cameraSpeed = nullptr;
|
||||||
AzQtComponents::DoubleSpinBox* m_gridSpinBox = nullptr;
|
AzQtComponents::DoubleSpinBox* m_gridSpinBox = nullptr;
|
||||||
AzQtComponents::DoubleSpinBox* m_angleSpinBox = nullptr;
|
AzQtComponents::DoubleSpinBox* m_angleSpinBox = nullptr;
|
||||||
@@ -184,7 +185,7 @@ protected:
|
|||||||
|
|
||||||
namespace AzToolsFramework
|
namespace AzToolsFramework
|
||||||
{
|
{
|
||||||
//! A component to reflect scriptable commands for the Editor
|
//! A component to reflect scriptable commands for the Editor.
|
||||||
class ViewportTitleDlgPythonFuncsHandler
|
class ViewportTitleDlgPythonFuncsHandler
|
||||||
: public AZ::Component
|
: public AZ::Component
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3408,7 +3408,14 @@ LUA_API const Node* lua_getDummyNode()
|
|||||||
const BehaviorParameter* arg = method->GetArgument(iArg);
|
const BehaviorParameter* arg = method->GetArgument(iArg);
|
||||||
BehaviorClass* argClass = nullptr;
|
BehaviorClass* argClass = nullptr;
|
||||||
LuaLoadFromStack fromStack = FromLuaStack(context, arg, argClass);
|
LuaLoadFromStack fromStack = FromLuaStack(context, arg, argClass);
|
||||||
AZ_Assert(fromStack, "Argument %s for Method %s doesn't have support to be converted to Lua!", arg->m_name, method->m_name.c_str());
|
AZ_Assert(fromStack,
|
||||||
|
"The argument type: %s for method: %s is not serialized and/or reflected for scripting.\n"
|
||||||
|
"Make sure %s is added to the SerializeContext and reflected to the BehaviorContext\n"
|
||||||
|
"For example, verify these two exist and are being called in a Reflect function:\n"
|
||||||
|
"serializeContext->Class<%s>();\n"
|
||||||
|
"behaviorContext->Class<%s>();\n"
|
||||||
|
"%s will not be available for scripting unless these requirements are met."
|
||||||
|
, arg->m_name, method->m_name.c_str(), arg->m_name, arg->m_name, arg->m_name, method->m_name.c_str());
|
||||||
|
|
||||||
m_fromLua.push_back(AZStd::make_pair(fromStack, argClass));
|
m_fromLua.push_back(AZStd::make_pair(fromStack, argClass));
|
||||||
}
|
}
|
||||||
@@ -5066,13 +5073,26 @@ LUA_API const Node* lua_getDummyNode()
|
|||||||
// Check all constructors if they have use ScriptDataContext and if so choose this one
|
// Check all constructors if they have use ScriptDataContext and if so choose this one
|
||||||
if (!customConstructorMethod)
|
if (!customConstructorMethod)
|
||||||
{
|
{
|
||||||
|
int overrideIndex = -1;
|
||||||
|
AZ::AttributeReader(nullptr, FindAttribute
|
||||||
|
( Script::Attributes::DefaultConstructorOverrideIndex, behaviorClass->m_attributes)).Read<int>(overrideIndex);
|
||||||
|
|
||||||
|
int methodIndex = 0;
|
||||||
for (BehaviorMethod* method : behaviorClass->m_constructors)
|
for (BehaviorMethod* method : behaviorClass->m_constructors)
|
||||||
{
|
{
|
||||||
|
if (methodIndex == overrideIndex)
|
||||||
|
{
|
||||||
|
customConstructorMethod = method;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (method->GetNumArguments() && method->GetArgument(method->GetNumArguments() - 1)->m_typeId == AZ::AzTypeInfo<ScriptDataContext>::Uuid())
|
if (method->GetNumArguments() && method->GetArgument(method->GetNumArguments() - 1)->m_typeId == AZ::AzTypeInfo<ScriptDataContext>::Uuid())
|
||||||
{
|
{
|
||||||
customConstructorMethod = method;
|
customConstructorMethod = method;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++methodIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace AZ
|
|||||||
static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
|
static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
|
||||||
static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function
|
static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function
|
||||||
static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script
|
static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script
|
||||||
|
static constexpr AZ::Crc32 DefaultConstructorOverrideIndex = AZ_CRC_CE("DefaultConstructorOverrideIndex"); ///< Use a different class constructor as the default constructor in Lua
|
||||||
static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
|
static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
|
||||||
static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script
|
static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script
|
||||||
static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
|
static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ namespace AZ
|
|||||||
const static AZ::Crc32 AllowClearAsset = AZ_CRC("AllowClearAsset", 0x24827182);
|
const static AZ::Crc32 AllowClearAsset = AZ_CRC("AllowClearAsset", 0x24827182);
|
||||||
// Show the name of the asset that was produced from the source asset
|
// Show the name of the asset that was produced from the source asset
|
||||||
const static AZ::Crc32 ShowProductAssetFileName = AZ_CRC("ShowProductAssetFileName");
|
const static AZ::Crc32 ShowProductAssetFileName = AZ_CRC("ShowProductAssetFileName");
|
||||||
|
//! Regular expression pattern filter for source files
|
||||||
|
const static AZ::Crc32 SourceAssetFilterPattern = AZ_CRC_CE("SourceAssetFilterPattern");
|
||||||
|
|
||||||
//! Component icon attributes
|
//! Component icon attributes
|
||||||
const static AZ::Crc32 Icon = AZ_CRC("Icon", 0x659429db);
|
const static AZ::Crc32 Icon = AZ_CRC("Icon", 0x659429db);
|
||||||
|
|||||||
@@ -204,6 +204,22 @@ namespace AZ
|
|||||||
// BaseJsonSerializer
|
// BaseJsonSerializer
|
||||||
//
|
//
|
||||||
|
|
||||||
|
JsonSerializationResult::Result BaseJsonSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||||
|
JsonDeserializerContext& context)
|
||||||
|
{
|
||||||
|
JsonSerializationResult::ResultCode result(JsonSerializationResult::Tasks::ReadField);
|
||||||
|
result.Combine(ContinueLoading(outputValue, outputValueTypeId, inputValue, context, ContinuationFlags::IgnoreTypeSerializer));
|
||||||
|
return context.Report(result, "Ignoring custom serialization during load");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonSerializationResult::Result BaseJsonSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||||
|
const Uuid& valueTypeId, JsonSerializerContext& context)
|
||||||
|
{
|
||||||
|
JsonSerializationResult::ResultCode result(JsonSerializationResult::Tasks::WriteValue);
|
||||||
|
result.Combine(ContinueStoring(outputValue, inputValue, defaultValue, valueTypeId, context, ContinuationFlags::IgnoreTypeSerializer));
|
||||||
|
return context.Report(result, "Ignoring custom serialization during store");
|
||||||
|
}
|
||||||
|
|
||||||
BaseJsonSerializer::OperationFlags BaseJsonSerializer::GetOperationsFlags() const
|
BaseJsonSerializer::OperationFlags BaseJsonSerializer::GetOperationsFlags() const
|
||||||
{
|
{
|
||||||
return OperationFlags::None;
|
return OperationFlags::None;
|
||||||
|
|||||||
@@ -180,13 +180,16 @@ namespace AZ
|
|||||||
|
|
||||||
//! Transforms the data from the rapidjson Value to outputValue, if the conversion is possible and supported.
|
//! Transforms the data from the rapidjson Value to outputValue, if the conversion is possible and supported.
|
||||||
//! The serializer is responsible for casting to the proper type and safely writing to the outputValue memory.
|
//! The serializer is responsible for casting to the proper type and safely writing to the outputValue memory.
|
||||||
|
//! \note The default implementation is to load the object ignoring a custom serializers for the type, which allows for custom serializers
|
||||||
|
//! to modify the object after all default loading has occurred.
|
||||||
virtual JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
virtual JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||||
JsonDeserializerContext& context) = 0;
|
JsonDeserializerContext& context);
|
||||||
|
|
||||||
//! Write the input value to a rapidjson value if the default value is not null and doesn't match the input value, otherwise
|
//! Write the input value to a rapidjson value if the default value is not null and doesn't match the input value, otherwise
|
||||||
//! an error is returned and sets the rapidjson value to a null value.
|
//! an error is returned and sets the rapidjson value to a null value.
|
||||||
|
//! \note The default implementation is to store the object ignoring custom serializers.
|
||||||
virtual JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
virtual JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||||
const Uuid& valueTypeId, JsonSerializerContext& context) = 0;
|
const Uuid& valueTypeId, JsonSerializerContext& context);
|
||||||
|
|
||||||
//! Returns the operation flags which tells the Json Serialization how this custom json serializer can be used.
|
//! Returns the operation flags which tells the Json Serialization how this custom json serializer can be used.
|
||||||
virtual OperationFlags GetOperationsFlags() const;
|
virtual OperationFlags GetOperationsFlags() const;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace AZ
|
|||||||
{
|
{
|
||||||
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
|
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
|
||||||
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
|
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
|
||||||
StoreTypeName(classData, context), context.GetJsonAllocator());
|
StoreTypeName(classData, classData.m_typeId, context), context.GetJsonAllocator());
|
||||||
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
|
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
|
||||||
}
|
}
|
||||||
return result.Combine(StoreClass(node, object, defaultObject, classData, context));
|
return result.Combine(StoreClass(node, object, defaultObject, classData, context));
|
||||||
@@ -531,7 +531,7 @@ namespace AZ
|
|||||||
return ResolvePointerResult::ContinueProcessing;
|
return ResolvePointerResult::ContinueProcessing;
|
||||||
}
|
}
|
||||||
|
|
||||||
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context)
|
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context)
|
||||||
{
|
{
|
||||||
rapidjson::Value result;
|
rapidjson::Value result;
|
||||||
AZStd::vector<Uuid> ids = context.GetSerializeContext()->FindClassId(Crc32(classData.m_name));
|
AZStd::vector<Uuid> ids = context.GetSerializeContext()->FindClassId(Crc32(classData.m_name));
|
||||||
@@ -544,7 +544,7 @@ namespace AZ
|
|||||||
// Only write the Uuid for the class if there are multiple classes sharing the same name.
|
// Only write the Uuid for the class if there are multiple classes sharing the same name.
|
||||||
// In this case it wouldn't be enough to determine which class needs to be used. The
|
// In this case it wouldn't be enough to determine which class needs to be used. The
|
||||||
// class name is still added as a comment for be friendlier for users to read.
|
// class name is still added as a comment for be friendlier for users to read.
|
||||||
AZStd::string fullName = classData.m_typeId.ToString<AZStd::string>();
|
AZStd::string fullName = typeId.ToString<AZStd::string>();
|
||||||
fullName += ' ';
|
fullName += ' ';
|
||||||
fullName += classData.m_name;
|
fullName += classData.m_name;
|
||||||
result.SetString(fullName.c_str(), aznumeric_caster(fullName.size()), context.GetJsonAllocator());
|
result.SetString(fullName.c_str(), aznumeric_caster(fullName.size()), context.GetJsonAllocator());
|
||||||
@@ -560,7 +560,7 @@ namespace AZ
|
|||||||
const SerializeContext::ClassData* data = context.GetSerializeContext()->FindClassData(typeId);
|
const SerializeContext::ClassData* data = context.GetSerializeContext()->FindClassData(typeId);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
output = JsonSerializer::StoreTypeName(*data, context);
|
output = JsonSerializer::StoreTypeName(*data, typeId, context);
|
||||||
return context.Report(Tasks::WriteValue, Outcomes::Success, "Type id successfully stored to json value.");
|
return context.Report(Tasks::WriteValue, Outcomes::Success, "Type id successfully stored to json value.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -580,7 +580,7 @@ namespace AZ
|
|||||||
{
|
{
|
||||||
rapidjson::Value insertedObject(rapidjson::kObjectType);
|
rapidjson::Value insertedObject(rapidjson::kObjectType);
|
||||||
insertedObject.AddMember(
|
insertedObject.AddMember(
|
||||||
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, context),
|
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, classData.m_typeId, context),
|
||||||
context.GetJsonAllocator());
|
context.GetJsonAllocator());
|
||||||
|
|
||||||
for (auto& element : output.GetObject())
|
for (auto& element : output.GetObject())
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace AZ
|
|||||||
const void*& object, const void*& defaultObject, AZStd::any& defaultObjectStorage,
|
const void*& object, const void*& defaultObject, AZStd::any& defaultObjectStorage,
|
||||||
const SerializeContext::ClassData*& elementClassData, const AZ::IRttiHelper& rtti, JsonSerializerContext& context);
|
const SerializeContext::ClassData*& elementClassData, const AZ::IRttiHelper& rtti, JsonSerializerContext& context);
|
||||||
|
|
||||||
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context);
|
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context);
|
||||||
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
|
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
|
||||||
const Uuid& typeId, JsonSerializerContext& context);
|
const Uuid& typeId, JsonSerializerContext& context);
|
||||||
|
|
||||||
|
|||||||
@@ -165,13 +165,12 @@ namespace AZ::Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
Container fileContent;
|
Container fileContent;
|
||||||
fileContent.resize(length);
|
fileContent.resize_no_construct(length);
|
||||||
AZ::IO::SizeType bytesRead = file.Read(length, fileContent.data());
|
AZ::IO::SizeType bytesRead = file.Read(length, fileContent.data());
|
||||||
file.Close();
|
file.Close();
|
||||||
|
|
||||||
// Resize again just in case bytesRead is less than length for some reason
|
// Resize again just in case bytesRead is less than length for some reason
|
||||||
fileContent.resize(bytesRead);
|
fileContent.resize_no_construct(bytesRead);
|
||||||
|
|
||||||
return AZ::Success(AZStd::move(fileContent));
|
return AZ::Success(AZStd::move(fileContent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,72 @@
|
|||||||
#include <Tests/Serialization/Json/JsonSerializationTests.h>
|
#include <Tests/Serialization/Json/JsonSerializationTests.h>
|
||||||
#include <Tests/Serialization/Json/TestCases_Classes.h>
|
#include <Tests/Serialization/Json/TestCases_Classes.h>
|
||||||
#include <Tests/Serialization/Json/TestCases_Pointers.h>
|
#include <Tests/Serialization/Json/TestCases_Pointers.h>
|
||||||
|
#include <AzCore/Asset/AssetCommon.h>
|
||||||
|
|
||||||
|
namespace AZ
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct SerializeGenericTypeInfo<JsonSerializationTests::TemplatedClass<T>>
|
||||||
|
{
|
||||||
|
using ThisType = JsonSerializationTests::TemplatedClass<T>;
|
||||||
|
|
||||||
|
class GenericTemplatedClassInfo : public GenericClassInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GenericTemplatedClassInfo()
|
||||||
|
: m_classData{ SerializeContext::ClassData::Create<ThisType>(
|
||||||
|
"TemplatedClass", "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", nullptr, nullptr) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeContext::ClassData* GetClassData() override
|
||||||
|
{
|
||||||
|
return &m_classData;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetNumTemplatedArguments() override
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Uuid& GetSpecializedTypeId() const override
|
||||||
|
{
|
||||||
|
return m_classData.m_typeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Uuid& GetGenericTypeId() const override
|
||||||
|
{
|
||||||
|
return m_classData.m_typeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Uuid& GetTemplatedTypeId(size_t element) override
|
||||||
|
{
|
||||||
|
(void)element;
|
||||||
|
return SerializeGenericTypeInfo<T>::GetClassTypeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reflect(SerializeContext* serializeContext) override
|
||||||
|
{
|
||||||
|
if (serializeContext)
|
||||||
|
{
|
||||||
|
serializeContext->RegisterGenericClassInfo(
|
||||||
|
GetSpecializedTypeId(), this, &AZ::AnyTypeInfoConcept<Data::Asset<Data::AssetData>>::CreateAny);
|
||||||
|
serializeContext->RegisterGenericClassInfo(
|
||||||
|
azrtti_typeid<ThisType>(), this,
|
||||||
|
&AZ::AnyTypeInfoConcept<ThisType>::CreateAny);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeContext::ClassData m_classData;
|
||||||
|
};
|
||||||
|
|
||||||
|
using ClassInfoType = GenericTemplatedClassInfo;
|
||||||
|
static ClassInfoType* GetGenericInfo()
|
||||||
|
{
|
||||||
|
return GetCurrentSerializeContextModule().CreateGenericClassInfo<ThisType>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace AZ
|
||||||
|
|
||||||
namespace JsonSerializationTests
|
namespace JsonSerializationTests
|
||||||
{
|
{
|
||||||
@@ -286,4 +352,32 @@ namespace JsonSerializationTests
|
|||||||
EXPECT_EQ(Processing::Halted, result.GetProcessing());
|
EXPECT_EQ(Processing::Halted, result.GetProcessing());
|
||||||
EXPECT_EQ(Outcomes::Unknown, result.GetOutcome());
|
EXPECT_EQ(Outcomes::Unknown, result.GetOutcome());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonSerializationTests, StoreTypeId_TemplatedType_StoresUuidWithName)
|
||||||
|
{
|
||||||
|
using namespace AZ;
|
||||||
|
using namespace AZ::JsonSerializationResult;
|
||||||
|
|
||||||
|
m_serializeContext->RegisterGenericType<TemplatedClass<A::Inherited>>();
|
||||||
|
m_serializeContext->RegisterGenericType<TemplatedClass<BaseClass>>();
|
||||||
|
|
||||||
|
Uuid input = azrtti_typeid<TemplatedClass<A::Inherited>>();
|
||||||
|
ResultCode result = JsonSerialization::StoreTypeId(
|
||||||
|
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
|
||||||
|
|
||||||
|
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||||
|
|
||||||
|
AZStd::string expected =
|
||||||
|
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<A::Inherited>>().ToString<AZStd::string>().c_str());
|
||||||
|
Expect_DocStrEq(expected.c_str(), false);
|
||||||
|
|
||||||
|
input = azrtti_typeid<TemplatedClass<BaseClass>>();
|
||||||
|
result = JsonSerialization::StoreTypeId(
|
||||||
|
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
|
||||||
|
|
||||||
|
expected =
|
||||||
|
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<BaseClass>>().ToString<AZStd::string>().c_str());
|
||||||
|
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||||
|
Expect_DocStrEq(expected.c_str(), false);
|
||||||
|
}
|
||||||
} // namespace JsonSerializationTests
|
} // namespace JsonSerializationTests
|
||||||
|
|||||||
+27
-2
@@ -9,9 +9,27 @@
|
|||||||
#include <AzToolsFramework/Application/EditorEntityManager.h>
|
#include <AzToolsFramework/Application/EditorEntityManager.h>
|
||||||
|
|
||||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||||
|
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||||
|
|
||||||
namespace AzToolsFramework
|
namespace AzToolsFramework
|
||||||
{
|
{
|
||||||
|
static bool AreEntitiesValidForDuplication(const EntityIdList& entityIds)
|
||||||
|
{
|
||||||
|
for (AZ::EntityId entityId : entityIds)
|
||||||
|
{
|
||||||
|
if (GetEntityById(entityId) == nullptr)
|
||||||
|
{
|
||||||
|
AZ_Error(
|
||||||
|
"Entity", false,
|
||||||
|
"Entity with id '%llu' is not found. This can happen when you try to duplicate the entity before it is created. Please "
|
||||||
|
"ensure entities are created before trying to duplicate them.",
|
||||||
|
static_cast<AZ::u64>(entityId));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorEntityManager::Start()
|
void EditorEntityManager::Start()
|
||||||
{
|
{
|
||||||
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
||||||
@@ -62,7 +80,11 @@ namespace AzToolsFramework
|
|||||||
EntityIdList selectedEntities;
|
EntityIdList selectedEntities;
|
||||||
ToolsApplicationRequestBus::BroadcastResult(selectedEntities, &ToolsApplicationRequests::GetSelectedEntities);
|
ToolsApplicationRequestBus::BroadcastResult(selectedEntities, &ToolsApplicationRequests::GetSelectedEntities);
|
||||||
|
|
||||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(selectedEntities);
|
if (AreEntitiesValidForDuplication(selectedEntities))
|
||||||
|
{
|
||||||
|
m_prefabPublicInterface->DuplicateEntitiesInInstance(selectedEntities);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorEntityManager::DuplicateEntityById(AZ::EntityId entityId)
|
void EditorEntityManager::DuplicateEntityById(AZ::EntityId entityId)
|
||||||
@@ -72,7 +94,10 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
void EditorEntityManager::DuplicateEntities(const EntityIdList& entities)
|
void EditorEntityManager::DuplicateEntities(const EntityIdList& entities)
|
||||||
{
|
{
|
||||||
m_prefabPublicInterface->DuplicateEntitiesInInstance(entities);
|
if (AreEntitiesValidForDuplication(entities))
|
||||||
|
{
|
||||||
|
m_prefabPublicInterface->DuplicateEntitiesInInstance(entities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,5 +34,4 @@ namespace AzToolsFramework
|
|||||||
private:
|
private:
|
||||||
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -99,6 +99,18 @@ namespace AzToolsFramework
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selection.GetSelectedAssetIds().empty())
|
||||||
|
{
|
||||||
|
for (auto& filePath : selection.GetSelectedFilePaths())
|
||||||
|
{
|
||||||
|
if (!filePath.empty())
|
||||||
|
{
|
||||||
|
selectedAsset = true;
|
||||||
|
m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!selectedAsset)
|
if (!selectedAsset)
|
||||||
{
|
{
|
||||||
m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory());
|
m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory());
|
||||||
|
|||||||
+60
-9
@@ -10,18 +10,24 @@
|
|||||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||||
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
||||||
|
|
||||||
|
#if !defined(Q_MOC_RUN)
|
||||||
|
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||||
|
#include <QRegExp>
|
||||||
|
AZ_POP_DISABLE_WARNING
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace AzToolsFramework
|
namespace AzToolsFramework
|
||||||
{
|
{
|
||||||
namespace AssetBrowser
|
namespace AssetBrowser
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
FilterConstType ProductsNoFoldersFilter()
|
FilterConstType EntryTypeNoFoldersFilter(AssetBrowserEntry::AssetEntryType entryType = AssetBrowserEntry::AssetEntryType::Product)
|
||||||
{
|
{
|
||||||
EntryTypeFilter* productFilter = new EntryTypeFilter();
|
EntryTypeFilter* entryTypeFilter = new EntryTypeFilter();
|
||||||
productFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Product);
|
entryTypeFilter->SetEntryType(entryType);
|
||||||
// in case entry is a source or folder, it may still contain relevant product
|
// in case entry is a source or folder, it may still contain relevant product
|
||||||
productFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
entryTypeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||||
|
|
||||||
EntryTypeFilter* foldersFilter = new EntryTypeFilter();
|
EntryTypeFilter* foldersFilter = new EntryTypeFilter();
|
||||||
foldersFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Folder);
|
foldersFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Folder);
|
||||||
@@ -30,7 +36,7 @@ namespace AzToolsFramework
|
|||||||
noFoldersFilter->SetFilter(FilterConstType(foldersFilter));
|
noFoldersFilter->SetFilter(FilterConstType(foldersFilter));
|
||||||
|
|
||||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||||
compFilter->AddFilter(FilterConstType(productFilter));
|
compFilter->AddFilter(FilterConstType(entryTypeFilter));
|
||||||
compFilter->AddFilter(FilterConstType(noFoldersFilter));
|
compFilter->AddFilter(FilterConstType(noFoldersFilter));
|
||||||
|
|
||||||
return FilterConstType(compFilter);
|
return FilterConstType(compFilter);
|
||||||
@@ -79,15 +85,39 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
void AssetSelectionModel::SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds)
|
void AssetSelectionModel::SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds)
|
||||||
{
|
{
|
||||||
|
m_selectedFilePaths.clear();
|
||||||
|
|
||||||
m_selectedAssetIds = selectedAssetIds;
|
m_selectedAssetIds = selectedAssetIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetSelectionModel::SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId)
|
void AssetSelectionModel::SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId)
|
||||||
{
|
{
|
||||||
|
m_selectedFilePaths.clear();
|
||||||
|
|
||||||
m_selectedAssetIds.clear();
|
m_selectedAssetIds.clear();
|
||||||
m_selectedAssetIds.push_back(selectedAssetId);
|
m_selectedAssetIds.push_back(selectedAssetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AZStd::vector<AZStd::string>& AssetSelectionModel::GetSelectedFilePaths() const
|
||||||
|
{
|
||||||
|
return m_selectedFilePaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetSelectionModel::SetSelectedFilePaths(const AZStd::vector<AZStd::string>& selectedFilePaths)
|
||||||
|
{
|
||||||
|
m_selectedAssetIds.clear();
|
||||||
|
|
||||||
|
m_selectedFilePaths = selectedFilePaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetSelectionModel::SetSelectedFilePath(const AZStd::string& selectedFilePath)
|
||||||
|
{
|
||||||
|
m_selectedAssetIds.clear();
|
||||||
|
|
||||||
|
m_selectedFilePaths.clear();
|
||||||
|
m_selectedFilePaths.push_back(selectedFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory)
|
void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory)
|
||||||
{
|
{
|
||||||
m_defaultDirectory = defaultDirectory;
|
m_defaultDirectory = defaultDirectory;
|
||||||
@@ -136,7 +166,7 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||||
compFilter->AddFilter(assetTypeFilterPtr);
|
compFilter->AddFilter(assetTypeFilterPtr);
|
||||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||||
|
|
||||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||||
selection.SetMultiselect(multiselect);
|
selection.SetMultiselect(multiselect);
|
||||||
@@ -169,7 +199,7 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||||
compFilter->AddFilter(anyAssetTypeFilterPtr);
|
compFilter->AddFilter(anyAssetTypeFilterPtr);
|
||||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||||
|
|
||||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||||
selection.SetMultiselect(multiselect);
|
selection.SetMultiselect(multiselect);
|
||||||
@@ -190,7 +220,28 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||||
compFilter->AddFilter(assetGroupFilterPtr);
|
compFilter->AddFilter(assetGroupFilterPtr);
|
||||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||||
|
|
||||||
|
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||||
|
selection.SetMultiselect(multiselect);
|
||||||
|
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetSelectionModel AssetSelectionModel::SourceAssetTypeSelection(const QString& pattern, bool multiselect)
|
||||||
|
{
|
||||||
|
AssetSelectionModel selection;
|
||||||
|
|
||||||
|
RegExpFilter* patternFilter = new RegExpFilter();
|
||||||
|
patternFilter->SetFilterPattern(pattern);
|
||||||
|
patternFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||||
|
auto patternFilterPtr = FilterConstType(patternFilter);
|
||||||
|
|
||||||
|
selection.SetDisplayFilter(patternFilterPtr);
|
||||||
|
|
||||||
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||||
|
compFilter->AddFilter(patternFilterPtr);
|
||||||
|
compFilter->AddFilter(EntryTypeNoFoldersFilter(AssetBrowserEntry::AssetEntryType::Source));
|
||||||
|
|
||||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||||
selection.SetMultiselect(multiselect);
|
selection.SetMultiselect(multiselect);
|
||||||
@@ -204,7 +255,7 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::OR);
|
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::OR);
|
||||||
selection.SetDisplayFilter(FilterConstType(compFilter));
|
selection.SetDisplayFilter(FilterConstType(compFilter));
|
||||||
selection.SetSelectionFilter(ProductsNoFoldersFilter());
|
selection.SetSelectionFilter(EntryTypeNoFoldersFilter());
|
||||||
selection.SetMultiselect(multiselect);
|
selection.SetMultiselect(multiselect);
|
||||||
|
|
||||||
return selection;
|
return selection;
|
||||||
|
|||||||
+10
-1
@@ -44,6 +44,10 @@ namespace AzToolsFramework
|
|||||||
void SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds);
|
void SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds);
|
||||||
void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId);
|
void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId);
|
||||||
|
|
||||||
|
const AZStd::vector<AZStd::string>& GetSelectedFilePaths() const;
|
||||||
|
void SetSelectedFilePaths(const AZStd::vector<AZStd::string>& selectedFilePaths);
|
||||||
|
void SetSelectedFilePath(const AZStd::string& selectedFilePath);
|
||||||
|
|
||||||
void SetDefaultDirectory(AZStd::string_view defaultDirectory);
|
void SetDefaultDirectory(AZStd::string_view defaultDirectory);
|
||||||
AZStd::string_view GetDefaultDirectory() const;
|
AZStd::string_view GetDefaultDirectory() const;
|
||||||
|
|
||||||
@@ -60,6 +64,7 @@ namespace AzToolsFramework
|
|||||||
static AssetSelectionModel AssetTypeSelection(const char* assetTypeName, bool multiselect = false);
|
static AssetSelectionModel AssetTypeSelection(const char* assetTypeName, bool multiselect = false);
|
||||||
static AssetSelectionModel AssetTypesSelection(const AZStd::vector<AZ::Data::AssetType>& assetTypes, bool multiselect = false);
|
static AssetSelectionModel AssetTypesSelection(const AZStd::vector<AZ::Data::AssetType>& assetTypes, bool multiselect = false);
|
||||||
static AssetSelectionModel AssetGroupSelection(const char* group, bool multiselect = false);
|
static AssetSelectionModel AssetGroupSelection(const char* group, bool multiselect = false);
|
||||||
|
static AssetSelectionModel SourceAssetTypeSelection(const QString& pattern, bool multiselect = false);
|
||||||
static AssetSelectionModel EverythingSelection(bool multiselect = false);
|
static AssetSelectionModel EverythingSelection(bool multiselect = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -68,8 +73,12 @@ namespace AzToolsFramework
|
|||||||
// some entries like folder should always be displayed, but not always selectable, thus 2 separate filters
|
// some entries like folder should always be displayed, but not always selectable, thus 2 separate filters
|
||||||
FilterConstType m_selectionFilter;
|
FilterConstType m_selectionFilter;
|
||||||
FilterConstType m_displayFilter;
|
FilterConstType m_displayFilter;
|
||||||
|
|
||||||
|
//! Selection can be based on asset ids (for products), or file paths (for sources)
|
||||||
|
//! These are mututally exclusive
|
||||||
AZStd::vector<AZ::Data::AssetId> m_selectedAssetIds;
|
AZStd::vector<AZ::Data::AssetId> m_selectedAssetIds;
|
||||||
|
AZStd::vector<AZStd::string> m_selectedFilePaths;
|
||||||
|
|
||||||
AZStd::vector<const AssetBrowserEntry*> m_results;
|
AZStd::vector<const AssetBrowserEntry*> m_results;
|
||||||
AZStd::string m_defaultDirectory;
|
AZStd::string m_defaultDirectory;
|
||||||
|
|
||||||
|
|||||||
@@ -251,6 +251,40 @@ namespace AzToolsFramework
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// RegExpFilter
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
RegExpFilter::RegExpFilter()
|
||||||
|
: m_filterPattern("")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegExpFilter::SetFilterPattern(const QString& filterPattern)
|
||||||
|
{
|
||||||
|
m_filterPattern = filterPattern;
|
||||||
|
Q_EMIT updatedSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RegExpFilter::GetNameInternal() const
|
||||||
|
{
|
||||||
|
return m_filterPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RegExpFilter::MatchInternal(const AssetBrowserEntry* entry) const
|
||||||
|
{
|
||||||
|
// no filter pattern matches any asset
|
||||||
|
if (m_filterPattern.isEmpty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// entry's name matches regular expression pattern
|
||||||
|
QRegExp regExp(m_filterPattern);
|
||||||
|
regExp.setPatternSyntax(QRegExp::Wildcard);
|
||||||
|
|
||||||
|
return regExp.exactMatch(entry->GetDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// AssetTypeFilter
|
// AssetTypeFilter
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -115,6 +115,28 @@ namespace AzToolsFramework
|
|||||||
QString m_filterString;
|
QString m_filterString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// RegExpFilter
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//! RegExpFilter filters assets based on a regular expression pattern
|
||||||
|
class RegExpFilter
|
||||||
|
: public AssetBrowserEntryFilter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
RegExpFilter();
|
||||||
|
~RegExpFilter() override = default;
|
||||||
|
|
||||||
|
void SetFilterPattern(const QString& filterPattern);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString GetNameInternal() const override;
|
||||||
|
bool MatchInternal(const AssetBrowserEntry* entry) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_filterPattern;
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// AssetTypeFilter
|
// AssetTypeFilter
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -1158,7 +1158,8 @@ namespace AzToolsFramework
|
|||||||
// Select the duplicated entities/instances
|
// Select the duplicated entities/instances
|
||||||
auto selectionUndo = aznew SelectionCommand(duplicatedEntityAndInstanceIds, "Select Duplicated Entities/Instances");
|
auto selectionUndo = aznew SelectionCommand(duplicatedEntityAndInstanceIds, "Select Duplicated Entities/Instances");
|
||||||
selectionUndo->SetParent(undoBatch.GetUndoBatch());
|
selectionUndo->SetParent(undoBatch.GetUndoBatch());
|
||||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, duplicatedEntityAndInstanceIds);
|
ToolsApplicationRequestBus::Broadcast(
|
||||||
|
&ToolsApplicationRequestBus::Events::SetSelectedEntities, duplicatedEntityAndInstanceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AZ::Success(AZStd::move(duplicatedEntityAndInstanceIds));
|
return AZ::Success(AZStd::move(duplicatedEntityAndInstanceIds));
|
||||||
|
|||||||
+11
-9
@@ -860,18 +860,20 @@ namespace AzToolsFramework
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDuringUndoRedo = false;
|
bool suppressTransformChangedEvent = m_suppressTransformChangedEvent;
|
||||||
EBUS_EVENT_RESULT(isDuringUndoRedo, AzToolsFramework::ToolsApplicationRequests::Bus, IsDuringUndoRedo);
|
// temporarily disable calling OnTransformChanged, because CheckApplyCachedWorldTransform is not guaranteed
|
||||||
if (!isDuringUndoRedo)
|
// to call it when m_cachedWorldTransform is identity. We send it manually later.
|
||||||
|
m_suppressTransformChangedEvent = false;
|
||||||
|
// When parent comes online, compute local TM from world TM.
|
||||||
|
CheckApplyCachedWorldTransform(parentTransform->GetWorldTM());
|
||||||
|
if (!m_initialized)
|
||||||
{
|
{
|
||||||
// When parent comes online, compute local TM from world TM.
|
m_initialized = true;
|
||||||
CheckApplyCachedWorldTransform(parentTransform->GetWorldTM());
|
// If this is the first time this entity is being activated, manually compute OnTransformChanged
|
||||||
}
|
// this can occur when either the entity first created or undo/redo command is performed
|
||||||
else
|
|
||||||
{
|
|
||||||
// During undo operations, just apply our local TM.
|
|
||||||
OnTransformChanged(AZ::Transform::Identity(), parentTransform->GetWorldTM());
|
OnTransformChanged(AZ::Transform::Identity(), parentTransform->GetWorldTM());
|
||||||
}
|
}
|
||||||
|
m_suppressTransformChangedEvent = suppressTransformChangedEvent;
|
||||||
|
|
||||||
auto& parentChildIds = GetParentTransformComponent()->m_childrenEntityIds;
|
auto& parentChildIds = GetParentTransformComponent()->m_childrenEntityIds;
|
||||||
if (parentChildIds.end() == AZStd::find(parentChildIds.begin(), parentChildIds.end(), GetEntityId()))
|
if (parentChildIds.end() == AZStd::find(parentChildIds.begin(), parentChildIds.end(), GetEntityId()))
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ namespace AzToolsFramework
|
|||||||
// element is used rather than a data element.
|
// element is used rather than a data element.
|
||||||
bool m_addNonUniformScaleButton = false;
|
bool m_addNonUniformScaleButton = false;
|
||||||
|
|
||||||
|
// Used to check whether entity was just created vs manually reactivated. Set true after OnEntityActivated is called the first time.
|
||||||
|
bool m_initialized = false;
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
AZ::InterpolationMode m_interpolatePosition;
|
AZ::InterpolationMode m_interpolatePosition;
|
||||||
AZ::InterpolationMode m_interpolateRotation;
|
AZ::InterpolationMode m_interpolateRotation;
|
||||||
|
|||||||
+22
-6
@@ -39,7 +39,12 @@ namespace AzToolsFramework
|
|||||||
typeFilter->SetAssetType(filterType);
|
typeFilter->SetAssetType(filterType);
|
||||||
typeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
typeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||||
|
|
||||||
m_assetBrowserFilterModel->SetFilter(FilterConstType(typeFilter));
|
SetFilter(FilterConstType(typeFilter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCompleterModel::SetFilter(FilterConstType filter)
|
||||||
|
{
|
||||||
|
m_assetBrowserFilterModel->SetFilter(filter);
|
||||||
|
|
||||||
RefreshAssetList();
|
RefreshAssetList();
|
||||||
}
|
}
|
||||||
@@ -120,9 +125,6 @@ namespace AzToolsFramework
|
|||||||
int rows = m_assetBrowserFilterModel->rowCount(index);
|
int rows = m_assetBrowserFilterModel->rowCount(index);
|
||||||
if (rows == 0)
|
if (rows == 0)
|
||||||
{
|
{
|
||||||
if (index != QModelIndex()) {
|
|
||||||
AZ_Error("AssetCompleterModel", false, "No children detected in FetchResources()");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ namespace AzToolsFramework
|
|||||||
QModelIndex childIndex = m_assetBrowserFilterModel->index(i, 0, index);
|
QModelIndex childIndex = m_assetBrowserFilterModel->index(i, 0, index);
|
||||||
AssetBrowserEntry* childEntry = GetAssetEntry(m_assetBrowserFilterModel->mapToSource(childIndex));
|
AssetBrowserEntry* childEntry = GetAssetEntry(m_assetBrowserFilterModel->mapToSource(childIndex));
|
||||||
|
|
||||||
if (childEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product)
|
if (childEntry->GetEntryType() == m_entryType)
|
||||||
{
|
{
|
||||||
ProductAssetBrowserEntry* productEntry = static_cast<ProductAssetBrowserEntry*>(childEntry);
|
ProductAssetBrowserEntry* productEntry = static_cast<ProductAssetBrowserEntry*>(childEntry);
|
||||||
AZStd::string assetName;
|
AZStd::string assetName;
|
||||||
@@ -167,7 +169,6 @@ namespace AzToolsFramework
|
|||||||
return m_assets[index.row()].m_displayName;
|
return m_assets[index.row()].m_displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const AZ::Data::AssetId AssetCompleterModel::GetAssetIdFromIndex(const QModelIndex& index)
|
const AZ::Data::AssetId AssetCompleterModel::GetAssetIdFromIndex(const QModelIndex& index)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
@@ -177,4 +178,19 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
return m_assets[index.row()].m_assetId;
|
return m_assets[index.row()].m_assetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AZStd::string_view AssetCompleterModel::GetPathFromIndex(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_assets[index.row()].m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCompleterModel::SetFetchEntryType(AssetBrowserEntry::AssetEntryType entryType)
|
||||||
|
{
|
||||||
|
m_entryType = entryType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -32,6 +32,7 @@ namespace AzToolsFramework
|
|||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
void SetFilter(AZ::Data::AssetType filterType);
|
void SetFilter(AZ::Data::AssetType filterType);
|
||||||
|
void SetFilter(FilterConstType filter);
|
||||||
void RefreshAssetList();
|
void RefreshAssetList();
|
||||||
void SearchStringHighlight(QString searchString);
|
void SearchStringHighlight(QString searchString);
|
||||||
|
|
||||||
@@ -39,6 +40,9 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
const AZStd::string_view GetNameFromIndex(const QModelIndex& index);
|
const AZStd::string_view GetNameFromIndex(const QModelIndex& index);
|
||||||
const AZ::Data::AssetId GetAssetIdFromIndex(const QModelIndex& index);
|
const AZ::Data::AssetId GetAssetIdFromIndex(const QModelIndex& index);
|
||||||
|
const AZStd::string_view GetPathFromIndex(const QModelIndex& index);
|
||||||
|
|
||||||
|
void SetFetchEntryType(AssetBrowserEntry::AssetEntryType entryType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AssetItem
|
struct AssetItem
|
||||||
@@ -57,6 +61,8 @@ namespace AzToolsFramework
|
|||||||
AZStd::vector<AssetItem> m_assets;
|
AZStd::vector<AssetItem> m_assets;
|
||||||
//! String that will be highlighted in the suggestions
|
//! String that will be highlighted in the suggestions
|
||||||
QString m_highlightString;
|
QString m_highlightString;
|
||||||
|
|
||||||
|
AssetBrowserEntry::AssetEntryType m_entryType = AssetBrowserEntry::AssetEntryType::Product;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -1288,7 +1288,7 @@ namespace AzToolsFramework
|
|||||||
return newCtrl;
|
return newCtrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetPropertyHandlerDefault::ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
void AssetPropertyHandlerDefault::ConsumeAttributeInternal(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
||||||
{
|
{
|
||||||
(void)debugName;
|
(void)debugName;
|
||||||
|
|
||||||
@@ -1487,6 +1487,11 @@ namespace AzToolsFramework
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetPropertyHandlerDefault::ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
||||||
|
{
|
||||||
|
ConsumeAttributeInternal(GUI, attrib, attrValue, debugName);
|
||||||
|
}
|
||||||
|
|
||||||
void AssetPropertyHandlerDefault::WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node)
|
void AssetPropertyHandlerDefault::WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node)
|
||||||
{
|
{
|
||||||
(void)index;
|
(void)index;
|
||||||
@@ -1629,8 +1634,8 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
void RegisterAssetPropertyHandler()
|
void RegisterAssetPropertyHandler()
|
||||||
{
|
{
|
||||||
EBUS_EVENT(PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew AssetPropertyHandlerDefault());
|
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew AssetPropertyHandlerDefault());
|
||||||
EBUS_EVENT(PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SimpleAssetPropertyHandlerDefault());
|
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew SimpleAssetPropertyHandlerDefault());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -175,10 +175,11 @@ namespace AzToolsFramework
|
|||||||
virtual void SetFolderSelection(const AZStd::string& /* folderPath */) {}
|
virtual void SetFolderSelection(const AZStd::string& /* folderPath */) {}
|
||||||
virtual void ClearAssetInternal();
|
virtual void ClearAssetInternal();
|
||||||
|
|
||||||
void ConfigureAutocompleter();
|
virtual void ConfigureAutocompleter();
|
||||||
void RefreshAutocompleter();
|
void RefreshAutocompleter();
|
||||||
void EnableAutocompleter();
|
void EnableAutocompleter();
|
||||||
void DisableAutocompleter();
|
void DisableAutocompleter();
|
||||||
|
const QModelIndex GetSourceIndex(const QModelIndex& index);
|
||||||
|
|
||||||
void HandleFieldClear();
|
void HandleFieldClear();
|
||||||
AZStd::string AddDefaultSuffix(const AZStd::string& filename);
|
AZStd::string AddDefaultSuffix(const AZStd::string& filename);
|
||||||
@@ -235,20 +236,19 @@ namespace AzToolsFramework
|
|||||||
void SetSelectedAssetID(const AZ::Data::AssetId& newID, const AZ::Data::AssetType& newType);
|
void SetSelectedAssetID(const AZ::Data::AssetId& newID, const AZ::Data::AssetType& newType);
|
||||||
void SetCurrentAssetHint(const AZStd::string& hint);
|
void SetCurrentAssetHint(const AZStd::string& hint);
|
||||||
void SetDefaultAssetID(const AZ::Data::AssetId& defaultID);
|
void SetDefaultAssetID(const AZ::Data::AssetId& defaultID);
|
||||||
void PopupAssetPicker();
|
virtual void PopupAssetPicker();
|
||||||
void OnClearButtonClicked();
|
void OnClearButtonClicked();
|
||||||
void UpdateAssetDisplay();
|
void UpdateAssetDisplay();
|
||||||
void OnLineEditFocus(bool focus);
|
void OnLineEditFocus(bool focus);
|
||||||
virtual void OnEditButtonClicked();
|
virtual void OnEditButtonClicked();
|
||||||
void OnThumbnailClicked();
|
void OnThumbnailClicked();
|
||||||
void OnCompletionModelReset();
|
void OnCompletionModelReset();
|
||||||
void OnAutocomplete(const QModelIndex& index);
|
virtual void OnAutocomplete(const QModelIndex& index);
|
||||||
void OnTextChange(const QString& text);
|
void OnTextChange(const QString& text);
|
||||||
void OnReturnPressed();
|
void OnReturnPressed();
|
||||||
void ShowContextMenu(const QPoint& pos);
|
void ShowContextMenu(const QPoint& pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QModelIndex GetSourceIndex(const QModelIndex& index);
|
|
||||||
void UpdateThumbnail();
|
void UpdateThumbnail();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -270,7 +270,8 @@ namespace AzToolsFramework
|
|||||||
virtual void UpdateWidgetInternalTabbing(PropertyAssetCtrl* widget) override { widget->UpdateTabOrder(); }
|
virtual void UpdateWidgetInternalTabbing(PropertyAssetCtrl* widget) override { widget->UpdateTabOrder(); }
|
||||||
|
|
||||||
virtual QWidget* CreateGUI(QWidget* pParent) override;
|
virtual QWidget* CreateGUI(QWidget* pParent) override;
|
||||||
virtual void ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName) override;
|
static void ConsumeAttributeInternal(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName);
|
||||||
|
void ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||||
virtual void WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node) override;
|
virtual void WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node) override;
|
||||||
virtual bool ReadValuesIntoGUI(size_t index, PropertyAssetCtrl* GUI, const property_t& instance, InstanceDataNode* node) override;
|
virtual bool ReadValuesIntoGUI(size_t index, PropertyAssetCtrl* GUI, const property_t& instance, InstanceDataNode* node) override;
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-4
@@ -3534,10 +3534,9 @@ namespace AzToolsFramework
|
|||||||
debugDisplay.SetLineWidth(1.0f);
|
debugDisplay.SetLineWidth(1.0f);
|
||||||
|
|
||||||
const float labelOffset = ed_viewportGizmoAxisLabelOffset;
|
const float labelOffset = ed_viewportGizmoAxisLabelOffset;
|
||||||
const float screenScale = GetScreenDisplayScaling(viewportId);
|
const auto labelXScreenPosition = (gizmoStart + (gizmoAxisX * labelOffset)) * editorCameraState.m_viewportSize;
|
||||||
const auto labelXScreenPosition = (gizmoStart + (gizmoAxisX * labelOffset)) * editorCameraState.m_viewportSize * screenScale;
|
const auto labelYScreenPosition = (gizmoStart + (gizmoAxisY * labelOffset)) * editorCameraState.m_viewportSize;
|
||||||
const auto labelYScreenPosition = (gizmoStart + (gizmoAxisY * labelOffset)) * editorCameraState.m_viewportSize * screenScale;
|
const auto labelZScreenPosition = (gizmoStart + (gizmoAxisZ * labelOffset)) * editorCameraState.m_viewportSize;
|
||||||
const auto labelZScreenPosition = (gizmoStart + (gizmoAxisZ * labelOffset)) * editorCameraState.m_viewportSize * screenScale;
|
|
||||||
|
|
||||||
// draw the label of of each axis for the gizmo
|
// draw the label of of each axis for the gizmo
|
||||||
const float labelSize = ed_viewportGizmoAxisLabelSize;
|
const float labelSize = ed_viewportGizmoAxisLabelSize;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include <AzCore/Component/TransformBus.h>
|
#include <AzCore/Component/TransformBus.h>
|
||||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||||
|
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||||
|
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||||
#include <Prefab/PrefabTestComponent.h>
|
#include <Prefab/PrefabTestComponent.h>
|
||||||
#include <Prefab/PrefabTestDomUtils.h>
|
#include <Prefab/PrefabTestDomUtils.h>
|
||||||
|
|
||||||
@@ -50,6 +52,15 @@ namespace UnitTest
|
|||||||
|
|
||||||
GetApplication()->RegisterComponentDescriptor(PrefabTestComponent::CreateDescriptor());
|
GetApplication()->RegisterComponentDescriptor(PrefabTestComponent::CreateDescriptor());
|
||||||
GetApplication()->RegisterComponentDescriptor(PrefabTestComponentWithUnReflectedTypeMember::CreateDescriptor());
|
GetApplication()->RegisterComponentDescriptor(PrefabTestComponentWithUnReflectedTypeMember::CreateDescriptor());
|
||||||
|
|
||||||
|
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
|
||||||
|
m_undoStack, &AzToolsFramework::ToolsApplicationRequestBus::Events::GetUndoStack);
|
||||||
|
AZ_Assert(m_undoStack, "Failed to look up undo stack from tools application");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefabTestFixture::TearDownEditorFixtureImpl()
|
||||||
|
{
|
||||||
|
m_undoStack = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AZStd::unique_ptr<ToolsTestApplication> PrefabTestFixture::CreateTestApplication()
|
AZStd::unique_ptr<ToolsTestApplication> PrefabTestFixture::CreateTestApplication()
|
||||||
@@ -57,7 +68,20 @@ namespace UnitTest
|
|||||||
return AZStd::make_unique<PrefabTestToolsApplication>("PrefabTestApplication");
|
return AZStd::make_unique<PrefabTestToolsApplication>("PrefabTestApplication");
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Entity* PrefabTestFixture::CreateEntity(const char* entityName, const bool shouldActivate)
|
void PrefabTestFixture::CreateRootPrefab()
|
||||||
|
{
|
||||||
|
auto entityOwnershipService = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
||||||
|
ASSERT_TRUE(entityOwnershipService != nullptr);
|
||||||
|
entityOwnershipService->CreateNewLevelPrefab("UnitTestRoot.prefab", "");
|
||||||
|
auto rootEntityReference = entityOwnershipService->GetRootPrefabInstance()->get().GetContainerEntity();
|
||||||
|
ASSERT_TRUE(rootEntityReference.has_value());
|
||||||
|
auto& rootEntity = rootEntityReference->get();
|
||||||
|
rootEntity.Deactivate();
|
||||||
|
rootEntity.CreateComponent<AzToolsFramework::Components::TransformComponent>();
|
||||||
|
rootEntity.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ::Entity* PrefabTestFixture::CreateEntity(AZStd::string entityName, const bool shouldActivate)
|
||||||
{
|
{
|
||||||
// Circumvent the EntityContext system and generate a new entity with a transformcomponent
|
// Circumvent the EntityContext system and generate a new entity with a transformcomponent
|
||||||
AZ::Entity* newEntity = aznew AZ::Entity(entityName);
|
AZ::Entity* newEntity = aznew AZ::Entity(entityName);
|
||||||
@@ -71,8 +95,43 @@ namespace UnitTest
|
|||||||
return newEntity;
|
return newEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AZ::EntityId PrefabTestFixture::CreateEntityUnderRootPrefab(AZStd::string name, AZ::EntityId parentId)
|
||||||
|
{
|
||||||
|
auto createResult = m_prefabPublicInterface->CreateEntity(parentId, AZ::Vector3());
|
||||||
|
AZ_Assert(createResult.IsSuccess(), "Failed to create entity: %s", createResult.GetError().c_str());
|
||||||
|
AZ::EntityId entityId = createResult.GetValue();
|
||||||
|
|
||||||
|
AZ::Entity* entity = nullptr;
|
||||||
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
|
||||||
|
|
||||||
|
entity->Deactivate();
|
||||||
|
|
||||||
|
entity->SetName(name);
|
||||||
|
|
||||||
|
// Normally, in invalid parent ID should automatically parent us to the root prefab, but currently in the unit test
|
||||||
|
// environment entities aren't created with a default transform component, so CreateEntity won't correctly parent.
|
||||||
|
// We get the actual target parent ID here, then create our missing transform component.
|
||||||
|
if (!parentId.IsValid())
|
||||||
|
{
|
||||||
|
auto prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
||||||
|
parentId = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance()->get().GetContainerEntityId();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto transform = aznew AzToolsFramework::Components::TransformComponent;
|
||||||
|
transform->SetParent(parentId);
|
||||||
|
entity->AddComponent(transform);
|
||||||
|
|
||||||
|
entity->Activate();
|
||||||
|
|
||||||
|
// Update our undo cache entry to include the rename / reparent as one atomic operation.
|
||||||
|
m_prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_undoStack->GetTop());
|
||||||
|
m_prefabSystemComponent->OnSystemTick();
|
||||||
|
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
void PrefabTestFixture::CompareInstances(const AzToolsFramework::Prefab::Instance& instanceA,
|
void PrefabTestFixture::CompareInstances(const AzToolsFramework::Prefab::Instance& instanceA,
|
||||||
const AzToolsFramework::Prefab::Instance& instanceB, bool shouldCompareLinkIds, bool shouldCompareContainerEntities)
|
const AzToolsFramework::Prefab::Instance& instanceB, bool shouldCompareLinkIds, bool shouldCompareContainerEntities)
|
||||||
{
|
{
|
||||||
AzToolsFramework::Prefab::TemplateId templateAId = instanceA.GetTemplateId();
|
AzToolsFramework::Prefab::TemplateId templateAId = instanceA.GetTemplateId();
|
||||||
AzToolsFramework::Prefab::TemplateId templateBId = instanceB.GetTemplateId();
|
AzToolsFramework::Prefab::TemplateId templateBId = instanceB.GetTemplateId();
|
||||||
@@ -125,4 +184,22 @@ namespace UnitTest
|
|||||||
EXPECT_EQ(entityInInstance->GetState(), AZ::Entity::State::Active);
|
EXPECT_EQ(entityInInstance->GetState(), AZ::Entity::State::Active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrefabTestFixture::ProcessDeferredUpdates()
|
||||||
|
{
|
||||||
|
// Force a prefab propagation for updates that are deferred to the next tick.
|
||||||
|
m_prefabSystemComponent->OnSystemTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefabTestFixture::Undo()
|
||||||
|
{
|
||||||
|
m_undoStack->Undo();
|
||||||
|
ProcessDeferredUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefabTestFixture::Redo()
|
||||||
|
{
|
||||||
|
m_undoStack->Redo();
|
||||||
|
ProcessDeferredUpdates();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,13 @@ namespace UnitTest
|
|||||||
inline static const char* CarPrefabMockFilePath = "SomePathToCar";
|
inline static const char* CarPrefabMockFilePath = "SomePathToCar";
|
||||||
|
|
||||||
void SetUpEditorFixtureImpl() override;
|
void SetUpEditorFixtureImpl() override;
|
||||||
|
void TearDownEditorFixtureImpl() override;
|
||||||
|
|
||||||
AZStd::unique_ptr<ToolsTestApplication> CreateTestApplication() override;
|
AZStd::unique_ptr<ToolsTestApplication> CreateTestApplication() override;
|
||||||
|
|
||||||
AZ::Entity* CreateEntity(const char* entityName, const bool shouldActivate = true);
|
void CreateRootPrefab();
|
||||||
|
AZ::Entity* CreateEntity(AZStd::string entityName, const bool shouldActivate = true);
|
||||||
|
AZ::EntityId CreateEntityUnderRootPrefab(AZStd::string name, AZ::EntityId parentId = AZ::EntityId());
|
||||||
|
|
||||||
void CompareInstances(const Instance& instanceA, const Instance& instanceB, bool shouldCompareLinkIds = true,
|
void CompareInstances(const Instance& instanceA, const Instance& instanceB, bool shouldCompareLinkIds = true,
|
||||||
bool shouldCompareContainerEntities = true);
|
bool shouldCompareContainerEntities = true);
|
||||||
@@ -62,10 +65,20 @@ namespace UnitTest
|
|||||||
//! Validates that all entities within a prefab instance are in 'Active' state.
|
//! Validates that all entities within a prefab instance are in 'Active' state.
|
||||||
void ValidateInstanceEntitiesActive(Instance& instance);
|
void ValidateInstanceEntitiesActive(Instance& instance);
|
||||||
|
|
||||||
|
// Kicks off any updates scheduled for the next tick
|
||||||
|
virtual void ProcessDeferredUpdates();
|
||||||
|
|
||||||
|
// Performs an undo operation and ensures the tick-scheduled updates happen
|
||||||
|
void Undo();
|
||||||
|
|
||||||
|
// Performs a redo operation and ensures the tick-scheduled updates happen
|
||||||
|
void Redo();
|
||||||
|
|
||||||
PrefabSystemComponent* m_prefabSystemComponent = nullptr;
|
PrefabSystemComponent* m_prefabSystemComponent = nullptr;
|
||||||
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
|
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
|
||||||
PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||||
InstanceUpdateExecutorInterface* m_instanceUpdateExecutorInterface = nullptr;
|
InstanceUpdateExecutorInterface* m_instanceUpdateExecutorInterface = nullptr;
|
||||||
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
|
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
|
||||||
|
AzToolsFramework::UndoSystem::UndoStack* m_undoStack = nullptr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@
|
|||||||
#include <AzFramework/Components/TransformComponent.h>
|
#include <AzFramework/Components/TransformComponent.h>
|
||||||
|
|
||||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||||
|
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||||
|
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||||
|
#include <Prefab/PrefabTestFixture.h>
|
||||||
|
|
||||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||||
|
|
||||||
@@ -1063,4 +1066,67 @@ R"DELIMITER(<ObjectStream version="1">
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fixture provides a root prefab with Transform component and listens for TransformNotificationBus.
|
||||||
|
class TransformComponentActivationTest
|
||||||
|
: public PrefabTestFixture
|
||||||
|
, public TransformNotificationBus::Handler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void SetUpEditorFixtureImpl() override
|
||||||
|
{
|
||||||
|
PrefabTestFixture::SetUpEditorFixtureImpl();
|
||||||
|
|
||||||
|
CreateRootPrefab();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDownEditorFixtureImpl() override
|
||||||
|
{
|
||||||
|
BusDisconnect();
|
||||||
|
|
||||||
|
PrefabTestFixture::TearDownEditorFixtureImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTransformChanged(const Transform& /*local*/, const Transform& /*world*/) override
|
||||||
|
{
|
||||||
|
m_transformUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveEntity(AZ::EntityId entityId)
|
||||||
|
{
|
||||||
|
AzToolsFramework::ScopedUndoBatch undoBatch("Move Entity");
|
||||||
|
TransformBus::Event(entityId, &TransformInterface::SetWorldTranslation, Vector3(1.f, 0.f, 0.f));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_transformUpdated = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(TransformComponentActivationTest, TransformChangedEventIsSentWhenEntityIsActivatedViaUndoRedo)
|
||||||
|
{
|
||||||
|
AZ::EntityId entityId = CreateEntityUnderRootPrefab("Entity");
|
||||||
|
MoveEntity(entityId);
|
||||||
|
BusConnect(entityId);
|
||||||
|
|
||||||
|
// verify that undoing/redoing move operations fires TransformChanged event
|
||||||
|
Undo();
|
||||||
|
EXPECT_TRUE(m_transformUpdated);
|
||||||
|
m_transformUpdated = false;
|
||||||
|
|
||||||
|
Redo();
|
||||||
|
EXPECT_TRUE(m_transformUpdated);
|
||||||
|
m_transformUpdated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TransformComponentActivationTest, TransformChangedEventIsNotSentWhenEntityIsDeactivatedAndActivated)
|
||||||
|
{
|
||||||
|
AZ::EntityId entityId = CreateEntityUnderRootPrefab("Entity");
|
||||||
|
BusConnect(entityId);
|
||||||
|
|
||||||
|
// verify that simply activating/deactivating an entity does not fire TransformChanged event
|
||||||
|
Entity* entity = nullptr;
|
||||||
|
ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
|
||||||
|
entity->Deactivate();
|
||||||
|
entity->Activate();
|
||||||
|
EXPECT_FALSE(m_transformUpdated);
|
||||||
|
}
|
||||||
} // namespace UnitTest
|
} // namespace UnitTest
|
||||||
|
|||||||
@@ -37,16 +37,11 @@ namespace UnitTest
|
|||||||
m_model->Initialize();
|
m_model->Initialize();
|
||||||
m_modelTester =
|
m_modelTester =
|
||||||
AZStd::make_unique<QAbstractItemModelTester>(m_model.get(), QAbstractItemModelTester::FailureReportingMode::Fatal);
|
AZStd::make_unique<QAbstractItemModelTester>(m_model.get(), QAbstractItemModelTester::FailureReportingMode::Fatal);
|
||||||
|
|
||||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
|
|
||||||
m_undoStack, &AzToolsFramework::ToolsApplicationRequestBus::Events::GetUndoStack);
|
|
||||||
AZ_Assert(m_undoStack, "Failed to look up undo stack from tools application");
|
|
||||||
|
|
||||||
// Create a new root prefab - the synthetic "NewLevel.prefab" that comes in by default isn't suitable for outliner tests
|
// Create a new root prefab - the synthetic "NewLevel.prefab" that comes in by default isn't suitable for outliner tests
|
||||||
// because it's created before the EditorEntityModel that our EntityOutlinerListModel subscribes to, and we want to
|
// because it's created before the EditorEntityModel that our EntityOutlinerListModel subscribes to, and we want to
|
||||||
// recreate it as part of the fixture regardless.
|
// recreate it as part of the fixture regardless.
|
||||||
auto entityOwnershipService = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
CreateRootPrefab();
|
||||||
entityOwnershipService->CreateNewLevelPrefab("UnitTestRoot.prefab", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDownEditorFixtureImpl() override
|
void TearDownEditorFixtureImpl() override
|
||||||
@@ -56,45 +51,7 @@ namespace UnitTest
|
|||||||
m_model.reset();
|
m_model.reset();
|
||||||
PrefabTestFixture::TearDownEditorFixtureImpl();
|
PrefabTestFixture::TearDownEditorFixtureImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an entity with a given name as one undoable operation
|
|
||||||
// Parents to parentId, or the root prefab container entity if parentId is invalid
|
|
||||||
AZ::EntityId CreateNamedEntity(AZStd::string name, AZ::EntityId parentId = AZ::EntityId())
|
|
||||||
{
|
|
||||||
auto createResult = m_prefabPublicInterface->CreateEntity(parentId, AZ::Vector3());
|
|
||||||
AZ_Assert(createResult.IsSuccess(), "Failed to create entity: %s", createResult.GetError().c_str());
|
|
||||||
AZ::EntityId entityId = createResult.GetValue();
|
|
||||||
|
|
||||||
AZ::Entity* entity = nullptr;
|
|
||||||
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
|
|
||||||
|
|
||||||
entity->Deactivate();
|
|
||||||
|
|
||||||
entity->SetName(name);
|
|
||||||
|
|
||||||
// Normally, in invalid parent ID should automatically parent us to the root prefab, but currently in the unit test
|
|
||||||
// environment entities aren't created with a default transform component, so CreateEntity won't correctly parent.
|
|
||||||
// We get the actual target parent ID here, then create our missing transform component.
|
|
||||||
if (!parentId.IsValid())
|
|
||||||
{
|
|
||||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
|
||||||
parentId = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance()->get().GetContainerEntityId();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto transform = aznew AzToolsFramework::Components::TransformComponent;
|
|
||||||
transform->SetParent(parentId);
|
|
||||||
entity->AddComponent(transform);
|
|
||||||
|
|
||||||
entity->Activate();
|
|
||||||
|
|
||||||
// Update our undo cache entry to include the rename / reparent as one atomic operation.
|
|
||||||
m_prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_undoStack->GetTop());
|
|
||||||
|
|
||||||
ProcessDeferredUpdates();
|
|
||||||
|
|
||||||
return entityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to visualize debug state
|
// Helper to visualize debug state
|
||||||
void PrintModel()
|
void PrintModel()
|
||||||
{
|
{
|
||||||
@@ -125,32 +82,16 @@ namespace UnitTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Kicks off any updates scheduled for the next tick
|
// Kicks off any updates scheduled for the next tick
|
||||||
void ProcessDeferredUpdates()
|
void ProcessDeferredUpdates() override
|
||||||
{
|
{
|
||||||
// Force a prefab propagation for updates that are deferred to the next tick.
|
PrefabTestFixture::ProcessDeferredUpdates();
|
||||||
m_prefabSystemComponent->OnSystemTick();
|
|
||||||
|
|
||||||
// Ensure the model process its entity update queue
|
// Ensure the model process its entity update queue
|
||||||
m_model->ProcessEntityUpdates();
|
m_model->ProcessEntityUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs an undo operation and ensures the tick-scheduled updates happen
|
|
||||||
void Undo()
|
|
||||||
{
|
|
||||||
m_undoStack->Undo();
|
|
||||||
ProcessDeferredUpdates();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Performs a redo operation and ensures the tick-scheduled updates happen
|
|
||||||
void Redo()
|
|
||||||
{
|
|
||||||
m_undoStack->Redo();
|
|
||||||
ProcessDeferredUpdates();
|
|
||||||
}
|
|
||||||
|
|
||||||
AZStd::unique_ptr<AzToolsFramework::EntityOutlinerListModel> m_model;
|
AZStd::unique_ptr<AzToolsFramework::EntityOutlinerListModel> m_model;
|
||||||
AZStd::unique_ptr<QAbstractItemModelTester> m_modelTester;
|
AZStd::unique_ptr<QAbstractItemModelTester> m_modelTester;
|
||||||
AzToolsFramework::UndoSystem::UndoStack* m_undoStack = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(EntityOutlinerTest, TestCreateFlatHierarchyUndoAndRedoWorks)
|
TEST_F(EntityOutlinerTest, TestCreateFlatHierarchyUndoAndRedoWorks)
|
||||||
@@ -159,7 +100,7 @@ namespace UnitTest
|
|||||||
|
|
||||||
for (size_t i = 0; i < entityCount; ++i)
|
for (size_t i = 0; i < entityCount; ++i)
|
||||||
{
|
{
|
||||||
CreateNamedEntity(AZStd::string::format("Entity%zu", i));
|
CreateEntityUnderRootPrefab(AZStd::string::format("Entity%zu", i));
|
||||||
EXPECT_EQ(m_model->rowCount(GetRootIndex()), i + 1);
|
EXPECT_EQ(m_model->rowCount(GetRootIndex()), i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +136,7 @@ namespace UnitTest
|
|||||||
AZ::EntityId parentId;
|
AZ::EntityId parentId;
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++)
|
||||||
{
|
{
|
||||||
parentId = CreateNamedEntity(AZStd::string::format("EntityDepth%i", i), parentId);
|
parentId = CreateEntityUnderRootPrefab(AZStd::string::format("EntityDepth%i", i), parentId);
|
||||||
EXPECT_EQ(modelDepth(), i + 1);
|
EXPECT_EQ(modelDepth(), i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ namespace AssetProcessor
|
|||||||
|
|
||||||
ExcludeAssetRecognizer excludeRecogniser;
|
ExcludeAssetRecognizer excludeRecogniser;
|
||||||
excludeRecogniser.m_name = "backup";
|
excludeRecogniser.m_name = "backup";
|
||||||
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher(".*\\/savebackup\\/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("(^|.+/)savebackup/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
||||||
config.AddExcludeRecognizer(excludeRecogniser);
|
config.AddExcludeRecognizer(excludeRecogniser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace AssetProcessor
|
|||||||
ExcludeAssetRecognizer excludeRecogniser;
|
ExcludeAssetRecognizer excludeRecogniser;
|
||||||
excludeRecogniser.m_name = "backup";
|
excludeRecogniser.m_name = "backup";
|
||||||
// we are excluding all the files in the folder but not the folder itself
|
// we are excluding all the files in the folder but not the folder itself
|
||||||
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher(".*\\/subfolder2\\/aaa\\/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("(^|[^/]+/)aaa/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
||||||
m_platformConfig.get()->AddExcludeRecognizer(excludeRecogniser);
|
m_platformConfig.get()->AddExcludeRecognizer(excludeRecogniser);
|
||||||
m_assetScanner.get()->StartScan();
|
m_assetScanner.get()->StartScan();
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ namespace AssetProcessor
|
|||||||
ExcludeAssetRecognizer excludeRecogniser;
|
ExcludeAssetRecognizer excludeRecogniser;
|
||||||
excludeRecogniser.m_name = "backup";
|
excludeRecogniser.m_name = "backup";
|
||||||
// we are excluding the complete folder here
|
// we are excluding the complete folder here
|
||||||
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher(".*\\/subfolder2\\/aaa", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("(^|[^/]+/)aaa", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
||||||
m_platformConfig.get()->AddExcludeRecognizer(excludeRecogniser);
|
m_platformConfig.get()->AddExcludeRecognizer(excludeRecogniser);
|
||||||
m_assetScanner.get()->StartScan();
|
m_assetScanner.get()->StartScan();
|
||||||
|
|
||||||
|
|||||||
+2
@@ -413,6 +413,8 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_RegularExcludes)
|
|||||||
auto configRoot = AZ::IO::FileIOBase::GetInstance()->ResolvePath("@exefolder@/testdata/config_regular");
|
auto configRoot = AZ::IO::FileIOBase::GetInstance()->ResolvePath("@exefolder@/testdata/config_regular");
|
||||||
ASSERT_TRUE(configRoot);
|
ASSERT_TRUE(configRoot);
|
||||||
UnitTestPlatformConfiguration config;
|
UnitTestPlatformConfiguration config;
|
||||||
|
|
||||||
|
config.AddScanFolder(ScanFolderInfo("blahblah", "Blah ScanFolder", "sf2", true, true), true);
|
||||||
m_absorber.Clear();
|
m_absorber.Clear();
|
||||||
ASSERT_TRUE(config.InitializeFromConfigFiles(configRoot->c_str(), testExeFolder->c_str(), projectPath.c_str(), false, false));
|
ASSERT_TRUE(config.InitializeFromConfigFiles(configRoot->c_str(), testExeFolder->c_str(), projectPath.c_str(), false, false));
|
||||||
ASSERT_EQ(m_absorber.m_numErrorsAbsorbed, 0);
|
ASSERT_EQ(m_absorber.m_numErrorsAbsorbed, 0);
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ namespace AssetProcessor
|
|||||||
|
|
||||||
ExcludeAssetRecognizer excludeRecogniser;
|
ExcludeAssetRecognizer excludeRecogniser;
|
||||||
excludeRecogniser.m_name = "backup";
|
excludeRecogniser.m_name = "backup";
|
||||||
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher(".*\\/savebackup\\/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
excludeRecogniser.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("(^|.+/)savebackup/.*", AssetBuilderSDK::AssetBuilderPattern::Regex);
|
||||||
config.AddExcludeRecognizer(excludeRecogniser);
|
config.AddExcludeRecognizer(excludeRecogniser);
|
||||||
|
|
||||||
AssetProcessorManager_Test apm(&config); // note, this will 'push' the scan folders in to the db.
|
AssetProcessorManager_Test apm(&config); // note, this will 'push' the scan folders in to the db.
|
||||||
@@ -1791,13 +1791,8 @@ namespace AssetProcessor
|
|||||||
UNIT_TEST_EXPECT_TRUE((newfingerprintForPCAfterVersionChange != fingerprintForPC) || (newfingerprintForPCAfterVersionChange != newfingerprintForPC));//Fingerprints should be different
|
UNIT_TEST_EXPECT_TRUE((newfingerprintForPCAfterVersionChange != fingerprintForPC) || (newfingerprintForPCAfterVersionChange != newfingerprintForPC));//Fingerprints should be different
|
||||||
UNIT_TEST_EXPECT_TRUE((newfingerprintForANDROIDAfterVersionChange != fingerprintForANDROID) || (newfingerprintForANDROIDAfterVersionChange != newfingerprintForANDROID));//Fingerprints should be different
|
UNIT_TEST_EXPECT_TRUE((newfingerprintForANDROIDAfterVersionChange != fingerprintForANDROID) || (newfingerprintForANDROIDAfterVersionChange != newfingerprintForANDROID));//Fingerprints should be different
|
||||||
|
|
||||||
//------Test for Files which are excluded
|
|
||||||
processResults.clear();
|
processResults.clear();
|
||||||
absolutePath = AssetUtilities::NormalizeFilePath(tempPath.absoluteFilePath("subfolder3/savebackup/test.txt"));
|
|
||||||
QMetaObject::invokeMethod(&apm, "AssessModifiedFile", Qt::QueuedConnection, Q_ARG(QString, absolutePath));
|
|
||||||
UNIT_TEST_EXPECT_FALSE(BlockUntil(idling, 3000)); //Processing a file that will be excluded should not cause assetprocessor manager to emit the onBecameIdle signal because its state should not change
|
|
||||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 0);
|
|
||||||
|
|
||||||
// ------------- Test querying asset status -------------------
|
// ------------- Test querying asset status -------------------
|
||||||
{
|
{
|
||||||
absolutePath = tempPath.absoluteFilePath("subfolder2/folder/ship.tiff");
|
absolutePath = tempPath.absoluteFilePath("subfolder2/folder/ship.tiff");
|
||||||
|
|||||||
@@ -1633,13 +1633,18 @@ namespace AssetProcessor
|
|||||||
|
|
||||||
bool AssetProcessor::PlatformConfiguration::IsFileExcluded(QString fileName) const
|
bool AssetProcessor::PlatformConfiguration::IsFileExcluded(QString fileName) const
|
||||||
{
|
{
|
||||||
for (const ExcludeAssetRecognizer& excludeRecognizer : m_excludeAssetRecognizers)
|
QString relPath, scanFolderName;
|
||||||
|
if (ConvertToRelativePath(fileName, relPath, scanFolderName))
|
||||||
{
|
{
|
||||||
if (excludeRecognizer.m_patternMatcher.MatchesPath(fileName.toUtf8().constData()))
|
for (const ExcludeAssetRecognizer& excludeRecognizer : m_excludeAssetRecognizers)
|
||||||
{
|
{
|
||||||
return true;
|
if (excludeRecognizer.m_patternMatcher.MatchesPath(relPath.toUtf8().constData()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -50,10 +50,10 @@
|
|||||||
"order": 6000
|
"order": 6000
|
||||||
},
|
},
|
||||||
"Exclude HoldFiles": {
|
"Exclude HoldFiles": {
|
||||||
"pattern": ".*\\\\/Levels\\\\/.*_hold\\\\/.*"
|
"pattern": "(^|.+/)Levels/.*_hold(/.*)?$"
|
||||||
},
|
},
|
||||||
"Exclude TempFiles": {
|
"Exclude TempFiles": {
|
||||||
"pattern": ".*\\\\/\\\\$tmp[0-9]*_.*"
|
"pattern": "(^|.+/)\\\\$tmp[0-9]*_.*"
|
||||||
},
|
},
|
||||||
"RC i_caf": {
|
"RC i_caf": {
|
||||||
"glob": "*.i_caf",
|
"glob": "*.i_caf",
|
||||||
|
|||||||
+2
-2
@@ -74,10 +74,10 @@
|
|||||||
"include": "test"
|
"include": "test"
|
||||||
},
|
},
|
||||||
"Exclude HoldFiles": {
|
"Exclude HoldFiles": {
|
||||||
"pattern": ".*\\\\/Levels\\\\/.*_hold\\\\/.*"
|
"pattern": "(^|.+/)Levels/.*_hold(/.*)?$"
|
||||||
},
|
},
|
||||||
"Exclude TempFiles": {
|
"Exclude TempFiles": {
|
||||||
"pattern": ".*\\\\/\\\\$tmp[0-9]*_.*"
|
"pattern": "(^|.+/)\\\\$tmp[0-9]*_.*"
|
||||||
},
|
},
|
||||||
"RC i_caf": {
|
"RC i_caf": {
|
||||||
"glob": "*.i_caf",
|
"glob": "*.i_caf",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace O3DE::ProjectManager
|
|||||||
QString targetBuildPath = QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix);
|
QString targetBuildPath = QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix);
|
||||||
|
|
||||||
return AZ::Success(QStringList{ ProjectCMakeCommand,
|
return AZ::Success(QStringList{ ProjectCMakeCommand,
|
||||||
|
"-G", "Visual Studio 16 2019",
|
||||||
"-B", targetBuildPath,
|
"-B", targetBuildPath,
|
||||||
"-S", m_projectInfo.m_path,
|
"-S", m_projectInfo.m_path,
|
||||||
QString("-DLY_3RDPARTY_PATH=").append(thirdPartyPath),
|
QString("-DLY_3RDPARTY_PATH=").append(thirdPartyPath),
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace O3DE::ProjectManager
|
|||||||
if (vsWhereFile.exists() && vsWhereFile.isFile())
|
if (vsWhereFile.exists() && vsWhereFile.isFile())
|
||||||
{
|
{
|
||||||
QStringList vsWhereBaseArguments = QStringList{"-version",
|
QStringList vsWhereBaseArguments = QStringList{"-version",
|
||||||
"16.9.2",
|
"[16.9.2,17)",
|
||||||
"-latest",
|
"-latest",
|
||||||
"-requires",
|
"-requires",
|
||||||
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"};
|
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"};
|
||||||
@@ -106,10 +106,8 @@ namespace O3DE::ProjectManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AZ::Failure(QObject::tr("Visual Studio 2019 version 16.9.2 or higher not found.<br><br>"
|
return AZ::Failure(QObject::tr("Visual Studio 2019 version 16.9.2 or higher not found.<br><br>"
|
||||||
"Visual Studio 2019 is required to build this project."
|
"A compatible version of Visual Studio is required to build this project.<br>"
|
||||||
" Install any edition of <a href='https://visualstudio.microsoft.com/downloads/'>Visual Studio 2019</a>"
|
"Refer to the <a href='https://o3de.org/docs/welcome-guide/requirements/#microsoft-visual-studio'>Visual Studio requirements</a> for more information."));
|
||||||
" or update to a newer version before proceeding to the next step."
|
|
||||||
" While installing configure Visual Studio with these <a href='https://o3de.org/docs/welcome-guide/setup/requirements/#visual-studio-configuration'>workloads</a>."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome<void, QString> OpenCMakeGUI(const QString& projectPath)
|
AZ::Outcome<void, QString> OpenCMakeGUI(const QString& projectPath)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
namespace O3DE::ProjectManager
|
namespace O3DE::ProjectManager
|
||||||
{
|
{
|
||||||
@@ -111,6 +112,11 @@ namespace O3DE::ProjectManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!RegisterEngine(interactive))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const AZ::CommandLine* commandLine = GetCommandLine();
|
const AZ::CommandLine* commandLine = GetCommandLine();
|
||||||
AZ_Assert(commandLine, "Failed to get command line");
|
AZ_Assert(commandLine, "Failed to get command line");
|
||||||
|
|
||||||
@@ -165,6 +171,85 @@ namespace O3DE::ProjectManager
|
|||||||
return m_entity != nullptr;
|
return m_entity != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::RegisterEngine(bool interactive)
|
||||||
|
{
|
||||||
|
// get this engine's info
|
||||||
|
auto engineInfoOutcome = m_pythonBindings->GetEngineInfo();
|
||||||
|
if (!engineInfoOutcome)
|
||||||
|
{
|
||||||
|
if (interactive)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(nullptr,
|
||||||
|
QObject::tr("Failed to get engine info"),
|
||||||
|
QObject::tr("A valid engine.json could not be found or loaded. "
|
||||||
|
"Please verify a valid engine.json file exists in %1")
|
||||||
|
.arg(GetEngineRoot()));
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ_Error("Project Manager", false, "Failed to get engine info");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineInfo engineInfo = engineInfoOutcome.GetValue();
|
||||||
|
if (engineInfo.m_registered)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if an engine with this name is already registered and has a valid engine.json
|
||||||
|
auto existingEngineResult = m_pythonBindings->GetEngineInfo(engineInfo.m_name);
|
||||||
|
if (existingEngineResult)
|
||||||
|
{
|
||||||
|
if (!interactive)
|
||||||
|
{
|
||||||
|
AZ_Error("Project Manager", false, "An engine with the name %s is already registered with the path %s",
|
||||||
|
engineInfo.m_name.toUtf8().constData(), engineInfo.m_path.toUtf8().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the updated engine name unless the user wants to cancel
|
||||||
|
bool okPressed = false;
|
||||||
|
const EngineInfo& otherEngineInfo = existingEngineResult.GetValue();
|
||||||
|
|
||||||
|
engineInfo.m_name = QInputDialog::getText(nullptr,
|
||||||
|
QObject::tr("Engine '%1' already registered").arg(engineInfo.m_name),
|
||||||
|
QObject::tr("An engine named '%1' is already registered.<br /><br />"
|
||||||
|
"<b>Current path</b><br />%2<br/><br />"
|
||||||
|
"<b>New path</b><br />%3<br /><br />"
|
||||||
|
"Press 'OK' to force registration, or provide a new engine name below.<br />"
|
||||||
|
"Alternatively, press `Cancel` to close the Project Manager and resolve the issue manually.")
|
||||||
|
.arg(engineInfo.m_name, otherEngineInfo.m_path, engineInfo.m_path),
|
||||||
|
QLineEdit::Normal,
|
||||||
|
engineInfo.m_name,
|
||||||
|
&okPressed);
|
||||||
|
|
||||||
|
if (!okPressed)
|
||||||
|
{
|
||||||
|
// user elected not to change the name or force registration
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// always force register in case there is an engine registered in o3de_manifest.json, but
|
||||||
|
// the engine.json is missing or corrupt in which case GetEngineInfo() fails
|
||||||
|
constexpr bool forceRegistration = true;
|
||||||
|
auto registerOutcome = m_pythonBindings->SetEngineInfo(engineInfo, forceRegistration);
|
||||||
|
if (!registerOutcome)
|
||||||
|
{
|
||||||
|
if (interactive)
|
||||||
|
{
|
||||||
|
ProjectUtils::DisplayDetailedError(QObject::tr("Failed to register engine"), registerOutcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ_Error("Project Manager", false, "Failed to register engine %s : %s",
|
||||||
|
engineInfo.m_path.toUtf8().constData(), registerOutcome.GetError().first.c_str());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::TearDown()
|
void Application::TearDown()
|
||||||
{
|
{
|
||||||
if (m_entity)
|
if (m_entity)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace O3DE::ProjectManager
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool InitLog(const char* logName);
|
bool InitLog(const char* logName);
|
||||||
|
bool RegisterEngine(bool interactive);
|
||||||
|
|
||||||
AZStd::unique_ptr<PythonBindings> m_pythonBindings;
|
AZStd::unique_ptr<PythonBindings> m_pythonBindings;
|
||||||
QSharedPointer<QCoreApplication> m_app;
|
QSharedPointer<QCoreApplication> m_app;
|
||||||
|
|||||||
@@ -25,13 +25,16 @@ namespace O3DE::ProjectManager
|
|||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_thirdPartyPath;
|
QString m_thirdPartyPath;
|
||||||
|
|
||||||
// from o3de_manifest.json
|
|
||||||
QString m_path;
|
QString m_path;
|
||||||
|
|
||||||
|
// from o3de_manifest.json
|
||||||
QString m_defaultProjectsFolder;
|
QString m_defaultProjectsFolder;
|
||||||
QString m_defaultGemsFolder;
|
QString m_defaultGemsFolder;
|
||||||
QString m_defaultTemplatesFolder;
|
QString m_defaultTemplatesFolder;
|
||||||
QString m_defaultRestrictedFolder;
|
QString m_defaultRestrictedFolder;
|
||||||
|
|
||||||
|
bool m_registered = false;
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
} // namespace O3DE::ProjectManager
|
} // namespace O3DE::ProjectManager
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <FormFolderBrowseEditWidget.h>
|
#include <FormFolderBrowseEditWidget.h>
|
||||||
#include <PythonBindingsInterface.h>
|
#include <PythonBindingsInterface.h>
|
||||||
#include <PathValidator.h>
|
#include <PathValidator.h>
|
||||||
|
#include <ProjectUtils.h>
|
||||||
#include <AzQtComponents/Utilities/DesktopUtilities.h>
|
#include <AzQtComponents/Utilities/DesktopUtilities.h>
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@@ -114,10 +115,10 @@ namespace O3DE::ProjectManager
|
|||||||
engineInfo.m_defaultGemsFolder = m_defaultGems->lineEdit()->text();
|
engineInfo.m_defaultGemsFolder = m_defaultGems->lineEdit()->text();
|
||||||
engineInfo.m_defaultTemplatesFolder = m_defaultProjectTemplates->lineEdit()->text();
|
engineInfo.m_defaultTemplatesFolder = m_defaultProjectTemplates->lineEdit()->text();
|
||||||
|
|
||||||
bool result = PythonBindingsInterface::Get()->SetEngineInfo(engineInfo);
|
auto result = PythonBindingsInterface::Get()->SetEngineInfo(engineInfo);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Engine Settings"), tr("Failed to save engine settings."));
|
ProjectUtils::DisplayDetailedError(tr("Failed to save engine settings"), result, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <GemRepo/GemRepoInspector.h>
|
#include <GemRepo/GemRepoInspector.h>
|
||||||
#include <PythonBindingsInterface.h>
|
#include <PythonBindingsInterface.h>
|
||||||
#include <ProjectManagerDefs.h>
|
#include <ProjectManagerDefs.h>
|
||||||
|
#include <ProjectUtils.h>
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
@@ -92,8 +93,7 @@ namespace O3DE::ProjectManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome < void,
|
auto addGemRepoResult = PythonBindingsInterface::Get()->AddGemRepo(repoUri);
|
||||||
AZStd::pair<AZStd::string, AZStd::string>> addGemRepoResult = PythonBindingsInterface::Get()->AddGemRepo(repoUri);
|
|
||||||
if (addGemRepoResult.IsSuccess())
|
if (addGemRepoResult.IsSuccess())
|
||||||
{
|
{
|
||||||
Reinit();
|
Reinit();
|
||||||
@@ -102,20 +102,7 @@ namespace O3DE::ProjectManager
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString failureMessage = tr("Failed to add gem repo: %1.").arg(repoUri);
|
QString failureMessage = tr("Failed to add gem repo: %1.").arg(repoUri);
|
||||||
if (!addGemRepoResult.GetError().second.empty())
|
ProjectUtils::DisplayDetailedError(failureMessage, addGemRepoResult, this);
|
||||||
{
|
|
||||||
QMessageBox addRepoError;
|
|
||||||
addRepoError.setIcon(QMessageBox::Critical);
|
|
||||||
addRepoError.setWindowTitle(failureMessage);
|
|
||||||
addRepoError.setText(addGemRepoResult.GetError().first.c_str());
|
|
||||||
addRepoError.setDetailedText(addGemRepoResult.GetError().second.c_str());
|
|
||||||
addRepoError.exec();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QMessageBox::critical(this, failureMessage, addGemRepoResult.GetError().first.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
AZ_Error("Project Manager", false, failureMessage.toUtf8());
|
AZ_Error("Project Manager", false, failureMessage.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -659,5 +659,24 @@ namespace O3DE::ProjectManager
|
|||||||
return AZ::Success(QString(projectBuildPath.c_str()));
|
return AZ::Success(QString(projectBuildPath.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayDetailedError(const QString& title, const AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>>& outcome, QWidget* parent)
|
||||||
|
{
|
||||||
|
const AZStd::string& generalError = outcome.GetError().first;
|
||||||
|
const AZStd::string& detailedError = outcome.GetError().second;
|
||||||
|
|
||||||
|
if (!detailedError.empty())
|
||||||
|
{
|
||||||
|
QMessageBox errorDialog(parent);
|
||||||
|
errorDialog.setIcon(QMessageBox::Critical);
|
||||||
|
errorDialog.setWindowTitle(title);
|
||||||
|
errorDialog.setText(generalError.c_str());
|
||||||
|
errorDialog.setDetailedText(detailedError.c_str());
|
||||||
|
errorDialog.exec();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::critical(parent, title, generalError.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace ProjectUtils
|
} // namespace ProjectUtils
|
||||||
} // namespace O3DE::ProjectManager
|
} // namespace O3DE::ProjectManager
|
||||||
|
|||||||
@@ -98,5 +98,14 @@ namespace O3DE::ProjectManager
|
|||||||
*/
|
*/
|
||||||
AZ::IO::FixedMaxPath GetEditorExecutablePath(const AZ::IO::PathView& projectPath);
|
AZ::IO::FixedMaxPath GetEditorExecutablePath(const AZ::IO::PathView& projectPath);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a dialog with general and detailed sections for the given AZ::Outcome
|
||||||
|
* @param title Dialog title
|
||||||
|
* @param outcome The AZ::Outcome with general and detailed error messages
|
||||||
|
* @param parent Optional QWidget parent
|
||||||
|
*/
|
||||||
|
void DisplayDetailedError(const QString& title, const AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>>& outcome, QWidget* parent = nullptr);
|
||||||
|
|
||||||
} // namespace ProjectUtils
|
} // namespace ProjectUtils
|
||||||
} // namespace O3DE::ProjectManager
|
} // namespace O3DE::ProjectManager
|
||||||
|
|||||||
@@ -312,6 +312,7 @@ namespace O3DE::ProjectManager
|
|||||||
m_register = pybind11::module::import("o3de.register");
|
m_register = pybind11::module::import("o3de.register");
|
||||||
m_manifest = pybind11::module::import("o3de.manifest");
|
m_manifest = pybind11::module::import("o3de.manifest");
|
||||||
m_engineTemplate = pybind11::module::import("o3de.engine_template");
|
m_engineTemplate = pybind11::module::import("o3de.engine_template");
|
||||||
|
m_engineProperties = pybind11::module::import("o3de.engine_properties");
|
||||||
m_enableGemProject = pybind11::module::import("o3de.enable_gem");
|
m_enableGemProject = pybind11::module::import("o3de.enable_gem");
|
||||||
m_disableGemProject = pybind11::module::import("o3de.disable_gem");
|
m_disableGemProject = pybind11::module::import("o3de.disable_gem");
|
||||||
m_editProjectProperties = pybind11::module::import("o3de.project_properties");
|
m_editProjectProperties = pybind11::module::import("o3de.project_properties");
|
||||||
@@ -319,9 +320,6 @@ namespace O3DE::ProjectManager
|
|||||||
m_repo = pybind11::module::import("o3de.repo");
|
m_repo = pybind11::module::import("o3de.repo");
|
||||||
m_pathlib = pybind11::module::import("pathlib");
|
m_pathlib = pybind11::module::import("pathlib");
|
||||||
|
|
||||||
// make sure the engine is registered
|
|
||||||
RegisterThisEngine();
|
|
||||||
|
|
||||||
m_pythonStarted = !PyErr_Occurred();
|
m_pythonStarted = !PyErr_Occurred();
|
||||||
return m_pythonStarted;
|
return m_pythonStarted;
|
||||||
}
|
}
|
||||||
@@ -346,36 +344,6 @@ namespace O3DE::ProjectManager
|
|||||||
return !PyErr_Occurred();
|
return !PyErr_Occurred();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PythonBindings::RegisterThisEngine()
|
|
||||||
{
|
|
||||||
bool registrationResult = true; // already registered is considered successful
|
|
||||||
bool pythonResult = ExecuteWithLock(
|
|
||||||
[&]
|
|
||||||
{
|
|
||||||
// check current engine path against all other registered engines
|
|
||||||
// to see if we are already registered
|
|
||||||
auto allEngines = m_manifest.attr("get_engines")();
|
|
||||||
if (pybind11::isinstance<pybind11::list>(allEngines))
|
|
||||||
{
|
|
||||||
for (auto engine : allEngines)
|
|
||||||
{
|
|
||||||
AZ::IO::FixedMaxPath enginePath(Py_To_String(engine));
|
|
||||||
if (enginePath.Compare(m_enginePath) == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = m_register.attr("register")(QString_To_Py_Path(QString(m_enginePath.c_str())));
|
|
||||||
registrationResult = (result.cast<int>() == 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
bool finalResult = (registrationResult && pythonResult);
|
|
||||||
AZ_Assert(finalResult, "Registration of this engine failed!");
|
|
||||||
return finalResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
AZ::Outcome<void, AZStd::string> PythonBindings::ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback)
|
AZ::Outcome<void, AZStd::string> PythonBindings::ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback)
|
||||||
{
|
{
|
||||||
if (!Py_IsInitialized())
|
if (!Py_IsInitialized())
|
||||||
@@ -407,16 +375,22 @@ namespace O3DE::ProjectManager
|
|||||||
return ExecuteWithLockErrorHandling(executionCallback).IsSuccess();
|
return ExecuteWithLockErrorHandling(executionCallback).IsSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
|
EngineInfo PythonBindings::EngineInfoFromPath(pybind11::handle enginePath)
|
||||||
{
|
{
|
||||||
EngineInfo engineInfo;
|
EngineInfo engineInfo;
|
||||||
bool result = ExecuteWithLock([&] {
|
try
|
||||||
auto enginePath = m_manifest.attr("get_this_engine_path")();
|
{
|
||||||
|
auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath);
|
||||||
|
if (pybind11::isinstance<pybind11::dict>(engineData))
|
||||||
|
{
|
||||||
|
engineInfo.m_version = Py_To_String_Optional(engineData, "O3DEVersion", "0.0.0.0");
|
||||||
|
engineInfo.m_name = Py_To_String_Optional(engineData, "engine_name", "O3DE");
|
||||||
|
engineInfo.m_path = Py_To_String(enginePath);
|
||||||
|
}
|
||||||
|
|
||||||
auto o3deData = m_manifest.attr("load_o3de_manifest")();
|
auto o3deData = m_manifest.attr("load_o3de_manifest")();
|
||||||
if (pybind11::isinstance<pybind11::dict>(o3deData))
|
if (pybind11::isinstance<pybind11::dict>(o3deData))
|
||||||
{
|
{
|
||||||
engineInfo.m_path = Py_To_String(enginePath);
|
|
||||||
auto defaultGemsFolder = m_manifest.attr("get_o3de_gems_folder")();
|
auto defaultGemsFolder = m_manifest.attr("get_o3de_gems_folder")();
|
||||||
engineInfo.m_defaultGemsFolder = Py_To_String_Optional(o3deData, "default_gems_folder", Py_To_String(defaultGemsFolder));
|
engineInfo.m_defaultGemsFolder = Py_To_String_Optional(o3deData, "default_gems_folder", Py_To_String(defaultGemsFolder));
|
||||||
|
|
||||||
@@ -433,19 +407,62 @@ namespace O3DE::ProjectManager
|
|||||||
engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData, "default_third_party_folder", Py_To_String(defaultThirdPartyFolder));
|
engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData, "default_third_party_folder", Py_To_String(defaultThirdPartyFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath);
|
// check if engine path is registered
|
||||||
if (pybind11::isinstance<pybind11::dict>(engineData))
|
auto allEngines = m_manifest.attr("get_engines")();
|
||||||
|
if (pybind11::isinstance<pybind11::list>(allEngines))
|
||||||
{
|
{
|
||||||
try
|
const AZ::IO::FixedMaxPath enginePathFixed(Py_To_String(enginePath));
|
||||||
|
for (auto engine : allEngines)
|
||||||
{
|
{
|
||||||
engineInfo.m_version = Py_To_String_Optional(engineData, "O3DEVersion", "0.0.0.0");
|
AZ::IO::FixedMaxPath otherEnginePath(Py_To_String(engine));
|
||||||
engineInfo.m_name = Py_To_String_Optional(engineData, "engine_name", "O3DE");
|
if (otherEnginePath.Compare(enginePathFixed) == 0)
|
||||||
}
|
{
|
||||||
catch ([[maybe_unused]] const std::exception& e)
|
engineInfo.m_registered = true;
|
||||||
{
|
break;
|
||||||
AZ_Warning("PythonBindings", false, "Failed to get EngineInfo from %s", Py_To_String(enginePath));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch ([[maybe_unused]] const std::exception& e)
|
||||||
|
{
|
||||||
|
AZ_Warning("PythonBindings", false, "Failed to get EngineInfo from %s", Py_To_String(enginePath));
|
||||||
|
}
|
||||||
|
return engineInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
|
||||||
|
{
|
||||||
|
EngineInfo engineInfo;
|
||||||
|
|
||||||
|
bool result = ExecuteWithLock([&] {
|
||||||
|
auto enginePath = m_manifest.attr("get_this_engine_path")();
|
||||||
|
engineInfo = EngineInfoFromPath(enginePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result || !engineInfo.IsValid())
|
||||||
|
{
|
||||||
|
return AZ::Failure();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return AZ::Success(AZStd::move(engineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo(const QString& engineName)
|
||||||
|
{
|
||||||
|
EngineInfo engineInfo;
|
||||||
|
bool result = ExecuteWithLock([&] {
|
||||||
|
auto enginePathResult = m_manifest.attr("get_registered")(QString_To_Py_String(engineName));
|
||||||
|
|
||||||
|
// if a valid registered object is not found None is returned
|
||||||
|
if (!pybind11::isinstance<pybind11::none>(enginePathResult))
|
||||||
|
{
|
||||||
|
engineInfo = EngineInfoFromPath(enginePathResult);
|
||||||
|
|
||||||
|
// it is possible an engine is registered in o3de_manifest.json but the engine.json is
|
||||||
|
// missing or corrupt in which case we do not consider it a registered engine
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result || !engineInfo.IsValid())
|
if (!result || !engineInfo.IsValid())
|
||||||
@@ -458,10 +475,32 @@ namespace O3DE::ProjectManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PythonBindings::SetEngineInfo(const EngineInfo& engineInfo)
|
IPythonBindings::DetailedOutcome PythonBindings::SetEngineInfo(const EngineInfo& engineInfo, bool force)
|
||||||
{
|
{
|
||||||
bool result = ExecuteWithLock([&] {
|
bool registrationSuccess = false;
|
||||||
auto registrationResult = m_register.attr("register")(
|
bool pythonSuccess = ExecuteWithLock([&] {
|
||||||
|
|
||||||
|
EngineInfo currentEngine = EngineInfoFromPath(QString_To_Py_Path(engineInfo.m_path));
|
||||||
|
|
||||||
|
// be kind to source control and avoid needlessly updating engine.json
|
||||||
|
if (currentEngine.IsValid() &&
|
||||||
|
(currentEngine.m_name.compare(engineInfo.m_name) != 0 || currentEngine.m_version.compare(engineInfo.m_version) != 0))
|
||||||
|
{
|
||||||
|
auto enginePropsResult = m_engineProperties.attr("edit_engine_props")(
|
||||||
|
QString_To_Py_Path(engineInfo.m_path),
|
||||||
|
pybind11::none(), // existing engine_name
|
||||||
|
QString_To_Py_String(engineInfo.m_name),
|
||||||
|
QString_To_Py_String(engineInfo.m_version)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (enginePropsResult.cast<int>() != 0)
|
||||||
|
{
|
||||||
|
// do not proceed with registration
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = m_register.attr("register")(
|
||||||
QString_To_Py_Path(engineInfo.m_path),
|
QString_To_Py_Path(engineInfo.m_path),
|
||||||
pybind11::none(), // project_path
|
pybind11::none(), // project_path
|
||||||
pybind11::none(), // gem_path
|
pybind11::none(), // gem_path
|
||||||
@@ -474,16 +513,22 @@ namespace O3DE::ProjectManager
|
|||||||
QString_To_Py_Path(engineInfo.m_defaultGemsFolder),
|
QString_To_Py_Path(engineInfo.m_defaultGemsFolder),
|
||||||
QString_To_Py_Path(engineInfo.m_defaultTemplatesFolder),
|
QString_To_Py_Path(engineInfo.m_defaultTemplatesFolder),
|
||||||
pybind11::none(), // default_restricted_folder
|
pybind11::none(), // default_restricted_folder
|
||||||
QString_To_Py_Path(engineInfo.m_thirdPartyPath)
|
QString_To_Py_Path(engineInfo.m_thirdPartyPath),
|
||||||
);
|
pybind11::none(), // external_subdir_engine_path
|
||||||
|
pybind11::none(), // external_subdir_project_path
|
||||||
|
false, // remove
|
||||||
|
force
|
||||||
|
);
|
||||||
|
|
||||||
if (registrationResult.cast<int>() != 0)
|
registrationSuccess = result.cast<int>() == 0;
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
if (pythonSuccess && registrationSuccess)
|
||||||
|
{
|
||||||
|
return AZ::Success();
|
||||||
|
}
|
||||||
|
|
||||||
|
return AZ::Failure<ErrorPair>(GetErrorPair());
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome<GemInfo> PythonBindings::GetGemInfo(const QString& path, const QString& projectPath)
|
AZ::Outcome<GemInfo> PythonBindings::GetGemInfo(const QString& path, const QString& projectPath)
|
||||||
@@ -1064,7 +1109,7 @@ namespace O3DE::ProjectManager
|
|||||||
return result && refreshResult;
|
return result && refreshResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> PythonBindings::AddGemRepo(const QString& repoUri)
|
IPythonBindings::DetailedOutcome PythonBindings::AddGemRepo(const QString& repoUri)
|
||||||
{
|
{
|
||||||
bool registrationResult = false;
|
bool registrationResult = false;
|
||||||
bool result = ExecuteWithLock(
|
bool result = ExecuteWithLock(
|
||||||
@@ -1080,7 +1125,7 @@ namespace O3DE::ProjectManager
|
|||||||
|
|
||||||
if (!result || !registrationResult)
|
if (!result || !registrationResult)
|
||||||
{
|
{
|
||||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(GetSimpleDetailedErrorPair());
|
return AZ::Failure<IPythonBindings::ErrorPair>(GetErrorPair());
|
||||||
}
|
}
|
||||||
|
|
||||||
return AZ::Success();
|
return AZ::Success();
|
||||||
@@ -1170,13 +1215,10 @@ namespace O3DE::ProjectManager
|
|||||||
return gemRepoInfo;
|
return gemRepoInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define MOCK_GEM_REPO_INFO true
|
|
||||||
|
|
||||||
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> PythonBindings::GetAllGemRepoInfos()
|
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> PythonBindings::GetAllGemRepoInfos()
|
||||||
{
|
{
|
||||||
QVector<GemRepoInfo> gemRepos;
|
QVector<GemRepoInfo> gemRepos;
|
||||||
|
|
||||||
#ifndef MOCK_GEM_REPO_INFO
|
|
||||||
auto result = ExecuteWithLockErrorHandling(
|
auto result = ExecuteWithLockErrorHandling(
|
||||||
[&]
|
[&]
|
||||||
{
|
{
|
||||||
@@ -1189,18 +1231,6 @@ namespace O3DE::ProjectManager
|
|||||||
{
|
{
|
||||||
return AZ::Failure<AZStd::string>(result.GetError().c_str());
|
return AZ::Failure<AZStd::string>(result.GetError().c_str());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
GemRepoInfo mockJohnRepo("JohnCreates", "John Smith", QDateTime(QDate(2021, 8, 31), QTime(11, 57)), true);
|
|
||||||
mockJohnRepo.m_summary = "John's Summary. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sollicitudin dapibus urna";
|
|
||||||
mockJohnRepo.m_repoUri = "https://github.com/o3de/o3de";
|
|
||||||
mockJohnRepo.m_additionalInfo = "John's additional info. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sollicitu.";
|
|
||||||
gemRepos.push_back(mockJohnRepo);
|
|
||||||
|
|
||||||
GemRepoInfo mockJaneRepo("JanesGems", "Jane Doe", QDateTime(QDate(2021, 9, 10), QTime(18, 23)), false);
|
|
||||||
mockJaneRepo.m_summary = "Jane's Summary.";
|
|
||||||
mockJaneRepo.m_repoUri = "https://github.com/o3de/o3de.org";
|
|
||||||
gemRepos.push_back(mockJaneRepo);
|
|
||||||
#endif // MOCK_GEM_REPO_INFO
|
|
||||||
|
|
||||||
std::sort(gemRepos.begin(), gemRepos.end());
|
std::sort(gemRepos.begin(), gemRepos.end());
|
||||||
return AZ::Success(AZStd::move(gemRepos));
|
return AZ::Success(AZStd::move(gemRepos));
|
||||||
@@ -1261,7 +1291,7 @@ namespace O3DE::ProjectManager
|
|||||||
return AZ::Success(AZStd::move(gemInfos));
|
return AZ::Success(AZStd::move(gemInfos));
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> PythonBindings::DownloadGem(
|
IPythonBindings::DetailedOutcome PythonBindings::DownloadGem(
|
||||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force)
|
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force)
|
||||||
{
|
{
|
||||||
// This process is currently limited to download a single gem at a time.
|
// This process is currently limited to download a single gem at a time.
|
||||||
@@ -1290,12 +1320,12 @@ namespace O3DE::ProjectManager
|
|||||||
|
|
||||||
if (!result.IsSuccess())
|
if (!result.IsSuccess())
|
||||||
{
|
{
|
||||||
AZStd::pair<AZStd::string, AZStd::string> pythonRunError(result.GetError(), result.GetError());
|
IPythonBindings::ErrorPair pythonRunError(result.GetError(), result.GetError());
|
||||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(AZStd::move(pythonRunError));
|
return AZ::Failure<IPythonBindings::ErrorPair>(AZStd::move(pythonRunError));
|
||||||
}
|
}
|
||||||
else if (!downloadSucceeded)
|
else if (!downloadSucceeded)
|
||||||
{
|
{
|
||||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(GetSimpleDetailedErrorPair());
|
return AZ::Failure<IPythonBindings::ErrorPair>(GetErrorPair());
|
||||||
}
|
}
|
||||||
|
|
||||||
return AZ::Success();
|
return AZ::Success();
|
||||||
@@ -1322,13 +1352,13 @@ namespace O3DE::ProjectManager
|
|||||||
return result && updateAvaliableResult;
|
return result && updateAvaliableResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
AZStd::pair<AZStd::string, AZStd::string> PythonBindings::GetSimpleDetailedErrorPair()
|
IPythonBindings::ErrorPair PythonBindings::GetErrorPair()
|
||||||
{
|
{
|
||||||
AZStd::string detailedString = m_pythonErrorStrings.size() == 1
|
AZStd::string detailedString = m_pythonErrorStrings.size() == 1
|
||||||
? ""
|
? ""
|
||||||
: AZStd::accumulate(m_pythonErrorStrings.begin(), m_pythonErrorStrings.end(), AZStd::string(""));
|
: AZStd::accumulate(m_pythonErrorStrings.begin(), m_pythonErrorStrings.end(), AZStd::string(""));
|
||||||
|
|
||||||
return AZStd::pair<AZStd::string, AZStd::string>(m_pythonErrorStrings.front(), detailedString);
|
return IPythonBindings::ErrorPair(m_pythonErrorStrings.front(), detailedString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonBindings::AddErrorString(AZStd::string errorString)
|
void PythonBindings::AddErrorString(AZStd::string errorString)
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ namespace O3DE::ProjectManager
|
|||||||
|
|
||||||
// Engine
|
// Engine
|
||||||
AZ::Outcome<EngineInfo> GetEngineInfo() override;
|
AZ::Outcome<EngineInfo> GetEngineInfo() override;
|
||||||
bool SetEngineInfo(const EngineInfo& engineInfo) override;
|
AZ::Outcome<EngineInfo> GetEngineInfo(const QString& engineName) override;
|
||||||
|
DetailedOutcome SetEngineInfo(const EngineInfo& engineInfo, bool force = false) override;
|
||||||
|
|
||||||
// Gem
|
// Gem
|
||||||
AZ::Outcome<GemInfo> GetGemInfo(const QString& path, const QString& projectPath = {}) override;
|
AZ::Outcome<GemInfo> GetGemInfo(const QString& path, const QString& projectPath = {}) override;
|
||||||
@@ -62,12 +63,12 @@ namespace O3DE::ProjectManager
|
|||||||
// Gem Repos
|
// Gem Repos
|
||||||
AZ::Outcome<void, AZStd::string> RefreshGemRepo(const QString& repoUri) override;
|
AZ::Outcome<void, AZStd::string> RefreshGemRepo(const QString& repoUri) override;
|
||||||
bool RefreshAllGemRepos() override;
|
bool RefreshAllGemRepos() override;
|
||||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> AddGemRepo(const QString& repoUri) override;
|
DetailedOutcome AddGemRepo(const QString& repoUri) override;
|
||||||
bool RemoveGemRepo(const QString& repoUri) override;
|
bool RemoveGemRepo(const QString& repoUri) override;
|
||||||
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
|
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
|
||||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForRepo(const QString& repoUri) override;
|
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForRepo(const QString& repoUri) override;
|
||||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForAllRepos() override;
|
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForAllRepos() override;
|
||||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> DownloadGem(
|
DetailedOutcome DownloadGem(
|
||||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
|
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
|
||||||
void CancelDownload() override;
|
void CancelDownload() override;
|
||||||
bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override;
|
bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override;
|
||||||
@@ -80,14 +81,14 @@ namespace O3DE::ProjectManager
|
|||||||
|
|
||||||
AZ::Outcome<void, AZStd::string> ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback);
|
AZ::Outcome<void, AZStd::string> ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback);
|
||||||
bool ExecuteWithLock(AZStd::function<void()> executionCallback);
|
bool ExecuteWithLock(AZStd::function<void()> executionCallback);
|
||||||
|
EngineInfo EngineInfoFromPath(pybind11::handle enginePath);
|
||||||
GemInfo GemInfoFromPath(pybind11::handle path, pybind11::handle pyProjectPath);
|
GemInfo GemInfoFromPath(pybind11::handle path, pybind11::handle pyProjectPath);
|
||||||
GemRepoInfo GetGemRepoInfo(pybind11::handle repoUri);
|
GemRepoInfo GetGemRepoInfo(pybind11::handle repoUri);
|
||||||
ProjectInfo ProjectInfoFromPath(pybind11::handle path);
|
ProjectInfo ProjectInfoFromPath(pybind11::handle path);
|
||||||
ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path, pybind11::handle pyProjectPath);
|
ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path, pybind11::handle pyProjectPath);
|
||||||
AZ::Outcome<void, AZStd::string> GemRegistration(const QString& gemPath, const QString& projectPath, bool remove = false);
|
AZ::Outcome<void, AZStd::string> GemRegistration(const QString& gemPath, const QString& projectPath, bool remove = false);
|
||||||
bool RegisterThisEngine();
|
|
||||||
bool StopPython();
|
bool StopPython();
|
||||||
AZStd::pair<AZStd::string, AZStd::string> GetSimpleDetailedErrorPair();
|
IPythonBindings::ErrorPair GetErrorPair();
|
||||||
|
|
||||||
|
|
||||||
bool m_pythonStarted = false;
|
bool m_pythonStarted = false;
|
||||||
@@ -96,6 +97,7 @@ namespace O3DE::ProjectManager
|
|||||||
AZStd::recursive_mutex m_lock;
|
AZStd::recursive_mutex m_lock;
|
||||||
|
|
||||||
pybind11::handle m_engineTemplate;
|
pybind11::handle m_engineTemplate;
|
||||||
|
pybind11::handle m_engineProperties;
|
||||||
pybind11::handle m_cmake;
|
pybind11::handle m_cmake;
|
||||||
pybind11::handle m_register;
|
pybind11::handle m_register;
|
||||||
pybind11::handle m_manifest;
|
pybind11::handle m_manifest;
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ namespace O3DE::ProjectManager
|
|||||||
IPythonBindings() = default;
|
IPythonBindings() = default;
|
||||||
virtual ~IPythonBindings() = default;
|
virtual ~IPythonBindings() = default;
|
||||||
|
|
||||||
|
//! First string in pair is general error, second is detailed
|
||||||
|
using ErrorPair = AZStd::pair<AZStd::string, AZStd::string>;
|
||||||
|
using DetailedOutcome = AZ::Outcome<void, ErrorPair>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get whether Python was started or not. All Python functionality will fail if Python
|
* Get whether Python was started or not. All Python functionality will fail if Python
|
||||||
* failed to start.
|
* failed to start.
|
||||||
@@ -49,17 +53,25 @@ namespace O3DE::ProjectManager
|
|||||||
// Engine
|
// Engine
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get info about the engine
|
* Get info about the current engine
|
||||||
* @return an outcome with EngineInfo on success
|
* @return an outcome with EngineInfo on success
|
||||||
*/
|
*/
|
||||||
virtual AZ::Outcome<EngineInfo> GetEngineInfo() = 0;
|
virtual AZ::Outcome<EngineInfo> GetEngineInfo() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set info about the engine
|
* Get info about an engine by name
|
||||||
* @param engineInfo an EngineInfo object
|
* @param engineName The name of the engine to get info about
|
||||||
|
* @return an outcome with EngineInfo on success
|
||||||
*/
|
*/
|
||||||
virtual bool SetEngineInfo(const EngineInfo& engineInfo) = 0;
|
virtual AZ::Outcome<EngineInfo> GetEngineInfo(const QString& engineName) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set info about the engine
|
||||||
|
* @param force True to force registration even if an engine with the same name is already registered
|
||||||
|
* @param engineInfo an EngineInfo object
|
||||||
|
* @return a detailed error outcome on failure.
|
||||||
|
*/
|
||||||
|
virtual DetailedOutcome SetEngineInfo(const EngineInfo& engineInfo, bool force = false) = 0;
|
||||||
|
|
||||||
// Gems
|
// Gems
|
||||||
|
|
||||||
@@ -202,7 +214,7 @@ namespace O3DE::ProjectManager
|
|||||||
* @param repoUri the absolute filesystem path or url to the gem repo.
|
* @param repoUri the absolute filesystem path or url to the gem repo.
|
||||||
* @return an outcome with a pair of string error and detailed messages on failure.
|
* @return an outcome with a pair of string error and detailed messages on failure.
|
||||||
*/
|
*/
|
||||||
virtual AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> AddGemRepo(const QString& repoUri) = 0;
|
virtual DetailedOutcome AddGemRepo(const QString& repoUri) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters this gem repo with the current engine.
|
* Unregisters this gem repo with the current engine.
|
||||||
@@ -237,7 +249,7 @@ namespace O3DE::ProjectManager
|
|||||||
* @param force should we forcibly overwrite the old version of the gem.
|
* @param force should we forcibly overwrite the old version of the gem.
|
||||||
* @return an outcome with a pair of string error and detailed messages on failure.
|
* @return an outcome with a pair of string error and detailed messages on failure.
|
||||||
*/
|
*/
|
||||||
virtual AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> DownloadGem(
|
virtual DetailedOutcome DownloadGem(
|
||||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) = 0;
|
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||||
"Name": "AlbedoWithGenericAlpha",
|
"Name": "AlbedoWithGenericAlpha",
|
||||||
"RGB_Weight": "CIEXYZ",
|
"RGB_Weight": "CIEXYZ",
|
||||||
"PixelFormat": "ASTC_4x4",
|
"PixelFormat": "BC3",
|
||||||
"MipMapSetting": {
|
"MipMapSetting": {
|
||||||
"MipGenType": "Box"
|
"MipGenType": "Box"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ namespace ImageProcessingAtom
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool IsASTCFormat(EPixelFormat fmt);
|
bool IsASTCFormat(EPixelFormat fmt);
|
||||||
|
bool IsHDRFormat(EPixelFormat fmt);
|
||||||
} // namespace ImageProcessingAtom
|
} // namespace ImageProcessingAtom
|
||||||
|
|
||||||
namespace AZ
|
namespace AZ
|
||||||
|
|||||||
+12
-2
@@ -620,6 +620,7 @@ namespace ImageProcessingAtom
|
|||||||
{
|
{
|
||||||
PresetName emptyPreset;
|
PresetName emptyPreset;
|
||||||
|
|
||||||
|
|
||||||
//get file mask of this image file
|
//get file mask of this image file
|
||||||
AZStd::string fileMask = GetFileMask(imageFilePath);
|
AZStd::string fileMask = GetFileMask(imageFilePath);
|
||||||
|
|
||||||
@@ -636,8 +637,17 @@ namespace ImageProcessingAtom
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (outPreset == emptyPreset)
|
if (outPreset == emptyPreset)
|
||||||
{
|
{
|
||||||
outPreset = m_defaultPreset;
|
auto image = IImageObjectPtr(LoadImageFromFile(imageFilePath));
|
||||||
|
if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent
|
||||||
|
|| image->GetAlphaContent() == EAlphaContent::eAlphaContent_OnlyWhite)
|
||||||
|
{
|
||||||
|
outPreset = m_defaultPreset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outPreset = m_defaultPresetAlpha;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outPreset;
|
return outPreset;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace ImageProcessingAtom
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
astcenc_profile GetAstcProfile(bool isSrgb, EPixelFormat pixelFormat)
|
astcenc_profile GetAstcProfile(bool isSrgb, bool isHDR)
|
||||||
{
|
{
|
||||||
// select profile depends on LDR or HDR, SRGB or Linear
|
// select profile depends on LDR or HDR, SRGB or Linear
|
||||||
// ASTCENC_PRF_LDR
|
// ASTCENC_PRF_LDR
|
||||||
@@ -86,8 +86,6 @@ namespace ImageProcessingAtom
|
|||||||
// ASTCENC_PRF_HDR_RGB_LDR_A
|
// ASTCENC_PRF_HDR_RGB_LDR_A
|
||||||
// ASTCENC_PRF_HDR
|
// ASTCENC_PRF_HDR
|
||||||
|
|
||||||
auto formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat);
|
|
||||||
bool isHDR = formatInfo->eSampleType == ESampleType::eSampleType_Half || formatInfo->eSampleType == ESampleType::eSampleType_Float;
|
|
||||||
astcenc_profile profile;
|
astcenc_profile profile;
|
||||||
if (isHDR)
|
if (isHDR)
|
||||||
{
|
{
|
||||||
@@ -170,7 +168,7 @@ namespace ImageProcessingAtom
|
|||||||
auto dstFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst);
|
auto dstFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst);
|
||||||
|
|
||||||
const float quality = GetAstcCompressQuality(compressOption->compressQuality);
|
const float quality = GetAstcCompressQuality(compressOption->compressQuality);
|
||||||
const astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), fmtSrc);
|
const astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), srcImage->HasImageFlags(EIF_HDR));
|
||||||
|
|
||||||
astcenc_config config;
|
astcenc_config config;
|
||||||
astcenc_error status;
|
astcenc_error status;
|
||||||
@@ -182,10 +180,12 @@ namespace ImageProcessingAtom
|
|||||||
// Create a context based on the configuration
|
// Create a context based on the configuration
|
||||||
astcenc_context* context;
|
astcenc_context* context;
|
||||||
AZ::u32 blockCount = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
|
AZ::u32 blockCount = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
|
||||||
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency(), blockCount);
|
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency()/2, blockCount);
|
||||||
status = astcenc_context_alloc(&config, threadCount, &context);
|
status = astcenc_context_alloc(&config, threadCount, &context);
|
||||||
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));
|
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));
|
||||||
|
|
||||||
|
AZ::Job* currentJob = AZ::JobContext::GetGlobalContext()->GetJobManager().GetCurrentJob();
|
||||||
|
|
||||||
const astcenc_type dataType =GetAstcDataType(fmtSrc);
|
const astcenc_type dataType =GetAstcDataType(fmtSrc);
|
||||||
|
|
||||||
// Compress the image for each mips
|
// Compress the image for each mips
|
||||||
@@ -209,29 +209,65 @@ namespace ImageProcessingAtom
|
|||||||
dstImage->GetImagePointer(mip, dstMem, dstPitch);
|
dstImage->GetImagePointer(mip, dstMem, dstPitch);
|
||||||
AZ::u32 dataSize = dstImage->GetMipBufSize(mip);
|
AZ::u32 dataSize = dstImage->GetMipBufSize(mip);
|
||||||
|
|
||||||
// Create jobs for each compression thread
|
if (threadCount == 1)
|
||||||
auto completionJob = aznew AZ::JobCompletion();
|
|
||||||
for (AZ::u32 threadIdx = 0; threadIdx < threadCount; threadIdx++)
|
|
||||||
{
|
{
|
||||||
const auto jobLambda = [&status, context, &image, &swizzle, dstMem, dataSize, threadIdx]()
|
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, 0);
|
||||||
|
if (error != ASTCENC_SUCCESS)
|
||||||
{
|
{
|
||||||
|
status = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AZ::JobCompletion* completionJob = nullptr;
|
||||||
|
if (!currentJob)
|
||||||
|
{
|
||||||
|
completionJob = aznew AZ::JobCompletion();
|
||||||
|
}
|
||||||
|
// Create jobs for each compression thread
|
||||||
|
for (AZ::u32 threadIdx = 0; threadIdx < threadCount; threadIdx++)
|
||||||
|
{
|
||||||
|
const auto jobLambda = [&status, context, &image, &swizzle, dstMem, dataSize, threadIdx]()
|
||||||
|
{
|
||||||
|
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
||||||
|
if (error != ASTCENC_SUCCESS)
|
||||||
|
{
|
||||||
|
status = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AZ::Job* simulationJob = AZ::CreateJobFunction(AZStd::move(jobLambda), true, nullptr); //auto-deletes
|
||||||
|
|
||||||
|
// adds this job as child to current job if there is a current job
|
||||||
|
// otherwise adds it as a dependent for the complete job
|
||||||
|
if (currentJob)
|
||||||
|
{
|
||||||
|
currentJob->StartAsChild(simulationJob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
simulationJob->SetDependent(completionJob);
|
||||||
|
simulationJob->Start();
|
||||||
|
}
|
||||||
|
|
||||||
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
||||||
if (error != ASTCENC_SUCCESS)
|
if (error != ASTCENC_SUCCESS)
|
||||||
{
|
{
|
||||||
status = error;
|
status = error;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
if (currentJob)
|
||||||
|
{
|
||||||
|
currentJob->WaitForChildren();
|
||||||
|
}
|
||||||
|
|
||||||
AZ::Job* simulationJob = AZ::CreateJobFunction(AZStd::move(jobLambda), true, nullptr); //auto-deletes
|
if (completionJob)
|
||||||
simulationJob->SetDependent(completionJob);
|
{
|
||||||
simulationJob->Start();
|
completionJob->StartAndWaitForCompletion();
|
||||||
}
|
delete completionJob;
|
||||||
|
completionJob = nullptr;
|
||||||
if (completionJob)
|
}
|
||||||
{
|
|
||||||
completionJob->StartAndWaitForCompletion();
|
|
||||||
delete completionJob;
|
|
||||||
completionJob = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != ASTCENC_SUCCESS)
|
if (status != ASTCENC_SUCCESS)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace ImageProcessingAtom
|
|||||||
builderDescriptor.m_busId = azrtti_typeid<ImageBuilderWorker>();
|
builderDescriptor.m_busId = azrtti_typeid<ImageBuilderWorker>();
|
||||||
builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||||
builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||||
builderDescriptor.m_version = 26; // [ATOM-15086]
|
builderDescriptor.m_version = 27; // [ATOM-16958]
|
||||||
builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint();
|
builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint();
|
||||||
m_imageBuilder.BusConnect(builderDescriptor.m_busId);
|
m_imageBuilder.BusConnect(builderDescriptor.m_busId);
|
||||||
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor);
|
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor);
|
||||||
@@ -221,18 +221,19 @@ namespace ImageProcessingAtom
|
|||||||
m_isShuttingDown = true;
|
m_isShuttingDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PresetName GetImagePreset(const AZStd::string& filepath)
|
PresetName GetImagePreset(const AZStd::string& imageFileFullPath)
|
||||||
{
|
{
|
||||||
// first let preset from asset info
|
// first let preset from asset info
|
||||||
TextureSettings textureSettings;
|
TextureSettings textureSettings;
|
||||||
StringOutcome output = TextureSettings::LoadTextureSetting(filepath, textureSettings);
|
AZStd::string settingFilePath = imageFileFullPath + TextureSettings::ExtensionName;
|
||||||
|
TextureSettings::LoadTextureSetting(settingFilePath, textureSettings);
|
||||||
|
|
||||||
if (!textureSettings.m_preset.IsEmpty())
|
if (!textureSettings.m_preset.IsEmpty())
|
||||||
{
|
{
|
||||||
return textureSettings.m_preset;
|
return textureSettings.m_preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuilderSettingManager::Instance()->GetSuggestedPreset(filepath);
|
return BuilderSettingManager::Instance()->GetSuggestedPreset(imageFileFullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlePresetDependency(PresetName presetName, AZStd::vector<AssetBuilderSDK::SourceFileDependency>& sourceDependencyList)
|
void HandlePresetDependency(PresetName presetName, AZStd::vector<AssetBuilderSDK::SourceFileDependency>& sourceDependencyList)
|
||||||
@@ -283,6 +284,10 @@ namespace ImageProcessingAtom
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Full path of the image file
|
||||||
|
AZStd::string fullPath;
|
||||||
|
AzFramework::StringFunc::Path::Join(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, true, true);
|
||||||
|
|
||||||
// Get the extension of the file
|
// Get the extension of the file
|
||||||
AZStd::string ext;
|
AZStd::string ext;
|
||||||
AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false);
|
AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false);
|
||||||
@@ -305,13 +310,12 @@ namespace ImageProcessingAtom
|
|||||||
// add source dependency for .assetinfo file
|
// add source dependency for .assetinfo file
|
||||||
AssetBuilderSDK::SourceFileDependency sourceFileDependency;
|
AssetBuilderSDK::SourceFileDependency sourceFileDependency;
|
||||||
sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute;
|
sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute;
|
||||||
sourceFileDependency.m_sourceFileDependencyPath = request.m_sourceFile;
|
sourceFileDependency.m_sourceFileDependencyPath = fullPath + TextureSettings::ExtensionName;
|
||||||
AZ::StringFunc::Path::ReplaceExtension(sourceFileDependency.m_sourceFileDependencyPath, TextureSettings::ExtensionName);
|
|
||||||
response.m_sourceFileDependencyList.push_back(sourceFileDependency);
|
response.m_sourceFileDependencyList.push_back(sourceFileDependency);
|
||||||
|
|
||||||
// add source dependencies for .preset files
|
// add source dependencies for .preset files
|
||||||
// Get the preset for this file
|
// Get the preset for this file
|
||||||
auto presetName = GetImagePreset(request.m_sourceFile);
|
auto presetName = GetImagePreset(fullPath.c_str());
|
||||||
HandlePresetDependency(presetName, response.m_sourceFileDependencyList);
|
HandlePresetDependency(presetName, response.m_sourceFileDependencyList);
|
||||||
|
|
||||||
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
|
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <ImageLoader/ImageLoaders.h>
|
#include <ImageLoader/ImageLoaders.h>
|
||||||
|
#include <Processing/ImageFlags.h>
|
||||||
#include <Atom/ImageProcessing/ImageObject.h>
|
#include <Atom/ImageProcessing/ImageObject.h>
|
||||||
// warning C4251: class QT_Type needs to have dll-interface to be used by clients of class 'QT_Type'
|
// warning C4251: class QT_Type needs to have dll-interface to be used by clients of class 'QT_Type'
|
||||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||||
@@ -26,21 +27,31 @@ namespace ImageProcessingAtom
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IImageObject* loadedImage = nullptr;
|
||||||
if (TIFFLoader::IsExtensionSupported(ext.toUtf8()))
|
if (TIFFLoader::IsExtensionSupported(ext.toUtf8()))
|
||||||
{
|
{
|
||||||
return TIFFLoader::LoadImageFromTIFF(filename);
|
loadedImage = TIFFLoader::LoadImageFromTIFF(filename);
|
||||||
}
|
}
|
||||||
else if (DdsLoader::IsExtensionSupported(ext.toUtf8()))
|
else if (DdsLoader::IsExtensionSupported(ext.toUtf8()))
|
||||||
{
|
{
|
||||||
return DdsLoader::LoadImageFromFile(filename);
|
loadedImage = DdsLoader::LoadImageFromFile(filename);
|
||||||
}
|
}
|
||||||
else if (QtImageLoader::IsExtensionSupported(ext.toUtf8()))
|
else if (QtImageLoader::IsExtensionSupported(ext.toUtf8()))
|
||||||
{
|
{
|
||||||
return QtImageLoader::LoadImageFromFile(filename);
|
loadedImage = QtImageLoader::LoadImageFromFile(filename);
|
||||||
}
|
}
|
||||||
else if (ExrLoader::IsExtensionSupported(ext.toUtf8()))
|
else if (ExrLoader::IsExtensionSupported(ext.toUtf8()))
|
||||||
{
|
{
|
||||||
return ExrLoader::LoadImageFromFile(filename);
|
loadedImage = ExrLoader::LoadImageFromFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadedImage)
|
||||||
|
{
|
||||||
|
if (IsHDRFormat(loadedImage->GetPixelFormat()))
|
||||||
|
{
|
||||||
|
loadedImage->AddImageFlags(EIF_HDR);
|
||||||
|
}
|
||||||
|
return loadedImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ_Warning("ImageProcessing", false, "No proper image loader to load file: %s", filename.c_str());
|
AZ_Warning("ImageProcessing", false, "No proper image loader to load file: %s", filename.c_str());
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ namespace ImageProcessingAtom
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_image->Get()->Swizzle(swizzle.c_str());
|
m_image->Get()->Swizzle(swizzle.c_str());
|
||||||
if (!m_input->m_presetSetting.m_discardAlpha)
|
if (m_input->m_presetSetting.m_discardAlpha)
|
||||||
{
|
{
|
||||||
m_alphaContent = EAlphaContent::eAlphaContent_Absent;
|
m_alphaContent = EAlphaContent::eAlphaContent_Absent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace ImageProcessingAtom
|
|||||||
const static AZ::u32 EIF_Decal = 0x4; // this is usually set through the preset
|
const static AZ::u32 EIF_Decal = 0x4; // this is usually set through the preset
|
||||||
const static AZ::u32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color
|
const static AZ::u32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color
|
||||||
const static AZ::u32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture
|
const static AZ::u32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture
|
||||||
const static AZ::u32 EIF_UNUSED_BIT = 0x40; // Free to use
|
const static AZ::u32 EIF_HDR = 0x40; // the image contains HDR data
|
||||||
const static AZ::u32 EIF_AttachedAlpha = 0x400; // deprecated: info for the engine: it's a texture with attached alpha channel
|
const static AZ::u32 EIF_AttachedAlpha = 0x400; // deprecated: info for the engine: it's a texture with attached alpha channel
|
||||||
const static AZ::u32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear)
|
const static AZ::u32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear)
|
||||||
const static AZ::u32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized
|
const static AZ::u32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized
|
||||||
|
|||||||
@@ -52,6 +52,24 @@ namespace ImageProcessingAtom
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsHDRFormat(EPixelFormat fmt)
|
||||||
|
{
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case ePixelFormat_BC6UH:
|
||||||
|
case ePixelFormat_R9G9B9E5:
|
||||||
|
case ePixelFormat_R32G32B32A32F:
|
||||||
|
case ePixelFormat_R32G32F:
|
||||||
|
case ePixelFormat_R32F:
|
||||||
|
case ePixelFormat_R16G16B16A16F:
|
||||||
|
case ePixelFormat_R16G16F:
|
||||||
|
case ePixelFormat_R16F:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PixelFormatInfo::PixelFormatInfo(
|
PixelFormatInfo::PixelFormatInfo(
|
||||||
uint32_t a_bitsPerPixel,
|
uint32_t a_bitsPerPixel,
|
||||||
uint32_t a_Channels,
|
uint32_t a_Channels,
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ namespace AZ
|
|||||||
AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialAssignmentSerializer, AZ::SystemAllocator, 0);
|
AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialAssignmentSerializer, AZ::SystemAllocator, 0);
|
||||||
|
|
||||||
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Load(
|
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Load(
|
||||||
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
void* outputValue,
|
||||||
|
[[maybe_unused]] const Uuid& outputValueTypeId,
|
||||||
|
const rapidjson::Value& inputValue,
|
||||||
JsonDeserializerContext& context)
|
JsonDeserializerContext& context)
|
||||||
{
|
{
|
||||||
namespace JSR = JsonSerializationResult;
|
namespace JSR = JsonSerializationResult;
|
||||||
@@ -62,6 +64,7 @@ namespace AZ
|
|||||||
LoadAny<AZ::Color>(propertyValue, inputPropertyPair.value, context, result) ||
|
LoadAny<AZ::Color>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||||
LoadAny<AZStd::string>(propertyValue, inputPropertyPair.value, context, result) ||
|
LoadAny<AZStd::string>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||||
LoadAny<AZ::Data::AssetId>(propertyValue, inputPropertyPair.value, context, result) ||
|
LoadAny<AZ::Data::AssetId>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||||
|
LoadAny<AZ::Data::Asset<AZ::Data::AssetData>>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||||
LoadAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, inputPropertyPair.value, context, result) ||
|
LoadAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||||
LoadAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, inputPropertyPair.value, context, result))
|
LoadAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, inputPropertyPair.value, context, result))
|
||||||
{
|
{
|
||||||
@@ -78,7 +81,10 @@ namespace AZ
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Store(
|
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Store(
|
||||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
|
rapidjson::Value& outputValue,
|
||||||
|
const void* inputValue,
|
||||||
|
const void* defaultValue,
|
||||||
|
[[maybe_unused]] const Uuid& valueTypeId,
|
||||||
JsonSerializerContext& context)
|
JsonSerializerContext& context)
|
||||||
{
|
{
|
||||||
namespace JSR = AZ::JsonSerializationResult;
|
namespace JSR = AZ::JsonSerializationResult;
|
||||||
@@ -138,9 +144,9 @@ namespace AZ
|
|||||||
StoreAny<AZ::Color>(propertyValue, outputPropertyValue, context, result) ||
|
StoreAny<AZ::Color>(propertyValue, outputPropertyValue, context, result) ||
|
||||||
StoreAny<AZStd::string>(propertyValue, outputPropertyValue, context, result) ||
|
StoreAny<AZStd::string>(propertyValue, outputPropertyValue, context, result) ||
|
||||||
StoreAny<AZ::Data::AssetId>(propertyValue, outputPropertyValue, context, result) ||
|
StoreAny<AZ::Data::AssetId>(propertyValue, outputPropertyValue, context, result) ||
|
||||||
|
StoreAny<AZ::Data::Asset<AZ::Data::AssetData>>(propertyValue, outputPropertyValue, context, result) ||
|
||||||
StoreAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, outputPropertyValue, context, result) ||
|
StoreAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, outputPropertyValue, context, result) ||
|
||||||
StoreAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(
|
StoreAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, outputPropertyValue, context, result))
|
||||||
propertyValue, outputPropertyValue, context, result))
|
|
||||||
{
|
{
|
||||||
outputPropertyValueContainer.AddMember(
|
outputPropertyValueContainer.AddMember(
|
||||||
rapidjson::Value::StringRefType(propertyName.GetCStr()), outputPropertyValue,
|
rapidjson::Value::StringRefType(propertyName.GetCStr()), outputPropertyValue,
|
||||||
@@ -164,7 +170,9 @@ namespace AZ
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool JsonMaterialAssignmentSerializer::LoadAny(
|
bool JsonMaterialAssignmentSerializer::LoadAny(
|
||||||
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context,
|
AZStd::any& propertyValue,
|
||||||
|
const rapidjson::Value& inputPropertyValue,
|
||||||
|
AZ::JsonDeserializerContext& context,
|
||||||
AZ::JsonSerializationResult::ResultCode& result)
|
AZ::JsonSerializationResult::ResultCode& result)
|
||||||
{
|
{
|
||||||
if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type"))
|
if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type"))
|
||||||
@@ -187,7 +195,9 @@ namespace AZ
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool JsonMaterialAssignmentSerializer::StoreAny(
|
bool JsonMaterialAssignmentSerializer::StoreAny(
|
||||||
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context,
|
const AZStd::any& propertyValue,
|
||||||
|
rapidjson::Value& outputPropertyValue,
|
||||||
|
AZ::JsonSerializerContext& context,
|
||||||
AZ::JsonSerializationResult::ResultCode& result)
|
AZ::JsonSerializationResult::ResultCode& result)
|
||||||
{
|
{
|
||||||
if (propertyValue.is<T>())
|
if (propertyValue.is<T>())
|
||||||
@@ -199,7 +209,7 @@ namespace AZ
|
|||||||
result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context));
|
result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context));
|
||||||
outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator());
|
outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator());
|
||||||
|
|
||||||
T value = AZStd::any_cast<T>(propertyValue);
|
const T& value = AZStd::any_cast<T>(propertyValue);
|
||||||
result.Combine(
|
result.Combine(
|
||||||
ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context));
|
ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -25,21 +25,31 @@ namespace AZ
|
|||||||
AZ_CLASS_ALLOCATOR_DECL;
|
AZ_CLASS_ALLOCATOR_DECL;
|
||||||
|
|
||||||
JsonSerializationResult::Result Load(
|
JsonSerializationResult::Result Load(
|
||||||
void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
void* outputValue,
|
||||||
|
const Uuid& outputValueTypeId,
|
||||||
|
const rapidjson::Value& inputValue,
|
||||||
JsonDeserializerContext& context) override;
|
JsonDeserializerContext& context) override;
|
||||||
|
|
||||||
JsonSerializationResult::Result Store(
|
JsonSerializationResult::Result Store(
|
||||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
|
rapidjson::Value& outputValue,
|
||||||
|
const void* inputValue,
|
||||||
|
const void* defaultValue,
|
||||||
|
const Uuid& valueTypeId,
|
||||||
JsonSerializerContext& context) override;
|
JsonSerializerContext& context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool LoadAny(
|
bool LoadAny(
|
||||||
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context,
|
AZStd::any& propertyValue,
|
||||||
|
const rapidjson::Value& inputPropertyValue,
|
||||||
|
AZ::JsonDeserializerContext& context,
|
||||||
AZ::JsonSerializationResult::ResultCode& result);
|
AZ::JsonSerializationResult::ResultCode& result);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool StoreAny(
|
bool StoreAny(
|
||||||
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context,
|
const AZStd::any& propertyValue,
|
||||||
|
rapidjson::Value& outputPropertyValue,
|
||||||
|
AZ::JsonSerializerContext& context,
|
||||||
AZ::JsonSerializationResult::ResultCode& result);
|
AZ::JsonSerializationResult::ResultCode& result);
|
||||||
};
|
};
|
||||||
} // namespace Render
|
} // namespace Render
|
||||||
|
|||||||
@@ -204,23 +204,19 @@ namespace AZ
|
|||||||
{
|
{
|
||||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||||
auto& device = static_cast<Device&>(GetDevice());
|
auto& device = static_cast<Device&>(GetDevice());
|
||||||
group.m_compiledDataIndex = (group.m_compiledDataIndex + 1) % RHI::Limits::Device::FrameCountMax;
|
|
||||||
|
|
||||||
if (!groupData.IsAnyResourceTypeUpdated())
|
if (!groupData.IsAnyResourceTypeUpdated())
|
||||||
{
|
{
|
||||||
return RHI::ResultCode::Success;
|
return RHI::ResultCode::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_constantBufferSize &&
|
group.m_compiledDataIndex = (group.m_compiledDataIndex + 1) % RHI::Limits::Device::FrameCountMax;
|
||||||
groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
if (m_constantBufferSize)
|
||||||
{
|
{
|
||||||
memcpy(group.GetCompiledData().m_cpuConstantAddress, groupData.GetConstantData().data(), groupData.GetConstantData().size());
|
memcpy(group.GetCompiledData().m_cpuConstantAddress, groupData.GetConstantData().data(), groupData.GetConstantData().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_viewsDescriptorTableSize &&
|
if (m_viewsDescriptorTableSize)
|
||||||
groupData.IsResourceTypeEnabledForCompilation(
|
|
||||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask) |
|
|
||||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
|
||||||
{
|
{
|
||||||
//Lazy initialization for cbv/srv/uav Descriptor Tables
|
//Lazy initialization for cbv/srv/uav Descriptor Tables
|
||||||
if (!group.m_viewsDescriptorTable.IsValid())
|
if (!group.m_viewsDescriptorTable.IsValid())
|
||||||
@@ -245,17 +241,12 @@ namespace AZ
|
|||||||
UpdateViewsDescriptorTable(descriptorTable, groupData);
|
UpdateViewsDescriptorTable(descriptorTable, groupData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_unboundedArrayCount &&
|
if (m_unboundedArrayCount)
|
||||||
groupData.IsResourceTypeEnabledForCompilation(
|
|
||||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewUnboundedArrayMask) |
|
|
||||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewUnboundedArrayMask)))
|
|
||||||
{
|
{
|
||||||
UpdateUnboundedArrayDescriptorTables(group, groupData);
|
UpdateUnboundedArrayDescriptorTables(group, groupData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_samplersDescriptorTableSize &&
|
if (m_samplersDescriptorTableSize)
|
||||||
groupData.IsResourceTypeEnabledForCompilation(
|
|
||||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
|
||||||
{
|
{
|
||||||
const DescriptorTable descriptorTable(
|
const DescriptorTable descriptorTable(
|
||||||
group.m_samplersDescriptorTable.GetOffset() + group.m_compiledDataIndex * m_samplersDescriptorTableSize,
|
group.m_samplersDescriptorTable.GetOffset() + group.m_compiledDataIndex * m_samplersDescriptorTableSize,
|
||||||
|
|||||||
@@ -61,10 +61,19 @@ namespace AZ
|
|||||||
|
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
id<MTLLibrary> lib = nil;
|
id<MTLLibrary> lib = nil;
|
||||||
|
|
||||||
|
bool loadFromByteCode = false;
|
||||||
|
|
||||||
|
// MacOS Big Sur (11.16.x) has issue loading some shader's byte code when GPUCapture(Metal) is on.
|
||||||
|
// Only enable it for Monterey (12.x)
|
||||||
|
if(@available(iOS 14.0, macOS 12.0, *))
|
||||||
|
{
|
||||||
|
loadFromByteCode = true;
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t* shaderByteCode = reinterpret_cast<const uint8_t*>(shaderFunction->GetByteCode().data());
|
const uint8_t* shaderByteCode = reinterpret_cast<const uint8_t*>(shaderFunction->GetByteCode().data());
|
||||||
const int byteCodeLength = shaderFunction->GetByteCode().size();
|
const int byteCodeLength = shaderFunction->GetByteCode().size();
|
||||||
if(byteCodeLength > 0 )
|
if(byteCodeLength > 0 && loadFromByteCode)
|
||||||
{
|
{
|
||||||
dispatch_data_t dispatchByteCodeData = dispatch_data_create(shaderByteCode, byteCodeLength, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
dispatch_data_t dispatchByteCodeData = dispatch_data_create(shaderByteCode, byteCodeLength, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
||||||
lib = [mtlDevice newLibraryWithData:dispatchByteCodeData error:&error];
|
lib = [mtlDevice newLibraryWithData:dispatchByteCodeData error:&error];
|
||||||
@@ -74,7 +83,7 @@ namespace AZ
|
|||||||
//In case byte code was not generated try to create the lib with source code
|
//In case byte code was not generated try to create the lib with source code
|
||||||
MTLCompileOptions* compileOptions = [MTLCompileOptions alloc];
|
MTLCompileOptions* compileOptions = [MTLCompileOptions alloc];
|
||||||
compileOptions.fastMathEnabled = YES;
|
compileOptions.fastMathEnabled = YES;
|
||||||
compileOptions.languageVersion = MTLLanguageVersion2_0;
|
compileOptions.languageVersion = MTLLanguageVersion2_2;
|
||||||
lib = [mtlDevice newLibraryWithSource:source
|
lib = [mtlDevice newLibraryWithSource:source
|
||||||
options:compileOptions
|
options:compileOptions
|
||||||
error:&error];
|
error:&error];
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AzCore/Debug/EventTrace.h>
|
|
||||||
#include <RHI/ArgumentBuffer.h>
|
#include <RHI/ArgumentBuffer.h>
|
||||||
#include <RHI/Conversions.h>
|
#include <RHI/Conversions.h>
|
||||||
#include <RHI/Device.h>
|
#include <RHI/Device.h>
|
||||||
@@ -62,57 +61,48 @@ namespace AZ
|
|||||||
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
||||||
{
|
{
|
||||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||||
group.UpdateCompiledDataIndex();
|
|
||||||
|
|
||||||
if (!groupData.IsAnyResourceTypeUpdated())
|
if (!groupData.IsAnyResourceTypeUpdated())
|
||||||
{
|
{
|
||||||
return RHI::ResultCode::Success;
|
return RHI::ResultCode::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group.UpdateCompiledDataIndex();
|
||||||
ArgumentBuffer& argBuffer = *group.m_compiledArgBuffers[group.m_compiledDataIndex];
|
ArgumentBuffer& argBuffer = *group.m_compiledArgBuffers[group.m_compiledDataIndex];
|
||||||
argBuffer.ClearResourceTracking();
|
argBuffer.ClearResourceTracking();
|
||||||
|
|
||||||
auto constantData = groupData.GetConstantData();
|
auto constantData = groupData.GetConstantData();
|
||||||
if (!constantData.empty() && groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
if (!constantData.empty())
|
||||||
{
|
{
|
||||||
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
||||||
}
|
}
|
||||||
|
|
||||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||||
uint32_t shaderInputIndex = 0;
|
uint32_t shaderInputIndex = 0;
|
||||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask)))
|
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
||||||
{
|
{
|
||||||
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
||||||
{
|
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
||||||
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
||||||
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
++shaderInputIndex;
|
||||||
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
|
||||||
++shaderInputIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
shaderInputIndex = 0;
|
||||||
|
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
||||||
{
|
{
|
||||||
shaderInputIndex = 0;
|
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
||||||
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
AZStd::array_view<RHI::SamplerState> samplerStates = groupData.GetSamplerArray(samplerInputIndex);
|
||||||
{
|
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
||||||
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
++shaderInputIndex;
|
||||||
AZStd::array_view<RHI::SamplerState> samplerStates = groupData.GetSamplerArray(samplerInputIndex);
|
|
||||||
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
|
||||||
++shaderInputIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
shaderInputIndex = 0;
|
||||||
|
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
||||||
{
|
{
|
||||||
shaderInputIndex = 0;
|
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
||||||
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
||||||
{
|
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
||||||
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
++shaderInputIndex;
|
||||||
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
|
||||||
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
|
||||||
++shaderInputIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RHI::ResultCode::Success;
|
return RHI::ResultCode::Success;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <AzCore/std/containers/vector.h>
|
#include <AzCore/std/containers/vector.h>
|
||||||
|
#include <AzCore/std/containers/fixed_vector.h>
|
||||||
#include <AzCore/std/parallel/lock.h>
|
#include <AzCore/std/parallel/lock.h>
|
||||||
#include <RHI/Buffer.h>
|
#include <RHI/Buffer.h>
|
||||||
#include <RHI/BufferView.h>
|
#include <RHI/BufferView.h>
|
||||||
@@ -688,8 +689,8 @@ namespace AZ
|
|||||||
if (interval != InvalidInterval)
|
if (interval != InvalidInterval)
|
||||||
{
|
{
|
||||||
uint32_t numBuffers = interval.m_max - interval.m_min + 1;
|
uint32_t numBuffers = interval.m_max - interval.m_min + 1;
|
||||||
AZStd::vector<VkBuffer> nativeBuffers(numBuffers, VK_NULL_HANDLE);
|
AZStd::fixed_vector<VkBuffer, RHI::Limits::Pipeline::StreamCountMax> nativeBuffers(numBuffers, VK_NULL_HANDLE);
|
||||||
AZStd::vector<VkDeviceSize> offsets(numBuffers, 0);
|
AZStd::fixed_vector<VkDeviceSize, RHI::Limits::Pipeline::StreamCountMax> offsets(numBuffers, 0);
|
||||||
for (uint32_t i = 0; i < numBuffers; ++i)
|
for (uint32_t i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
const RHI::StreamBufferView& bufferView = streams[i + interval.m_min];
|
const RHI::StreamBufferView& bufferView = streams[i + interval.m_min];
|
||||||
|
|||||||
@@ -104,13 +104,13 @@ namespace AZ
|
|||||||
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
||||||
{
|
{
|
||||||
auto& group = static_cast<ShaderResourceGroup&>(groupBase);
|
auto& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||||
group.UpdateCompiledDataIndex(m_currentIteration);
|
|
||||||
|
|
||||||
if (!groupData.IsAnyResourceTypeUpdated())
|
if (!groupData.IsAnyResourceTypeUpdated())
|
||||||
{
|
{
|
||||||
return RHI::ResultCode::Success;
|
return RHI::ResultCode::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group.UpdateCompiledDataIndex(m_currentIteration);
|
||||||
DescriptorSet& descriptorSet = *group.m_compiledData[group.GetCompileDataIndex()];
|
DescriptorSet& descriptorSet = *group.m_compiledData[group.GetCompileDataIndex()];
|
||||||
|
|
||||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ namespace AtomToolsFramework
|
|||||||
{
|
{
|
||||||
if (value.Is<AZ::Data::Asset<AZ::RPI::ImageAsset>>())
|
if (value.Is<AZ::Data::Asset<AZ::RPI::ImageAsset>>())
|
||||||
{
|
{
|
||||||
const AZ::Data::Asset<AZ::RPI::ImageAsset>& imageAsset = value.GetValue<AZ::Data::Asset<AZ::RPI::ImageAsset>>();
|
const auto& imageAsset = value.GetValue<AZ::Data::Asset<AZ::RPI::ImageAsset>>();
|
||||||
return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>(
|
return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>(imageAsset.GetId(), azrtti_typeid<AZ::RPI::StreamingImageAsset>(), imageAsset.GetHint()));
|
||||||
imageAsset.GetId(),
|
}
|
||||||
azrtti_typeid<AZ::RPI::StreamingImageAsset>(),
|
else if (value.Is<AZ::Data::Instance<AZ::RPI::Image>>())
|
||||||
imageAsset.GetHint()));
|
{
|
||||||
|
const auto& image = value.GetValue<AZ::Data::Instance<AZ::RPI::Image>>();
|
||||||
|
return AZStd::any(AZ::Data::Asset<AZ::RPI::StreamingImageAsset>(image->GetAssetId(), azrtti_typeid<AZ::RPI::StreamingImageAsset>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return AZ::RPI::MaterialPropertyValue::ToAny(value);
|
return AZ::RPI::MaterialPropertyValue::ToAny(value);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
// Sample Gems, Block source folders
|
// Sample Gems, Block source folders
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
"Exclude Work In Progress Folders": {
|
"Exclude Work In Progress Folders": {
|
||||||
"pattern": ".*\\\\/.[Ss]rc\\\\/.*"
|
"pattern": "(^|.+/).[Ss]rc(/.*)?$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1362,8 +1362,9 @@ namespace AZ::AtomBridge
|
|||||||
// if 2d draw need to project pos to screen first
|
// if 2d draw need to project pos to screen first
|
||||||
AzFramework::TextDrawParameters params;
|
AzFramework::TextDrawParameters params;
|
||||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||||
|
const auto dpiScaleFactor = viewportContext->GetDpiScalingFactor();
|
||||||
params.m_drawViewportId = viewportContext->GetId(); // get the viewport ID so default viewport works
|
params.m_drawViewportId = viewportContext->GetId(); // get the viewport ID so default viewport works
|
||||||
params.m_position = AZ::Vector3(x, y, 1.0f);
|
params.m_position = AZ::Vector3(x * dpiScaleFactor, y * dpiScaleFactor, 1.0f);
|
||||||
params.m_color = m_rendState.m_color;
|
params.m_color = m_rendState.m_color;
|
||||||
params.m_scale = AZ::Vector2(size);
|
params.m_scale = AZ::Vector2(size);
|
||||||
params.m_hAlign = center ? AzFramework::TextHorizontalAlignment::Center : AzFramework::TextHorizontalAlignment::Left; //! Horizontal text alignment
|
params.m_hAlign = center ? AzFramework::TextHorizontalAlignment::Center : AzFramework::TextHorizontalAlignment::Left; //! Horizontal text alignment
|
||||||
|
|||||||
+33
@@ -104,6 +104,7 @@ namespace AZ
|
|||||||
MaterialComponentController::MaterialComponentController(const MaterialComponentConfig& config)
|
MaterialComponentController::MaterialComponentController(const MaterialComponentConfig& config)
|
||||||
: m_configuration(config)
|
: m_configuration(config)
|
||||||
{
|
{
|
||||||
|
ConvertAssetsForSerialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialComponentController::Activate(EntityId entityId)
|
void MaterialComponentController::Activate(EntityId entityId)
|
||||||
@@ -135,6 +136,7 @@ namespace AZ
|
|||||||
void MaterialComponentController::SetConfiguration(const MaterialComponentConfig& config)
|
void MaterialComponentController::SetConfiguration(const MaterialComponentConfig& config)
|
||||||
{
|
{
|
||||||
m_configuration = config;
|
m_configuration = config;
|
||||||
|
ConvertAssetsForSerialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MaterialComponentConfig& MaterialComponentController::GetConfiguration() const
|
const MaterialComponentConfig& MaterialComponentController::GetConfiguration() const
|
||||||
@@ -338,6 +340,7 @@ namespace AZ
|
|||||||
// before LoadMaterials() is called [LYN-2249]
|
// before LoadMaterials() is called [LYN-2249]
|
||||||
auto temp = m_configuration.m_materials;
|
auto temp = m_configuration.m_materials;
|
||||||
m_configuration.m_materials = materials;
|
m_configuration.m_materials = materials;
|
||||||
|
ConvertAssetsForSerialization();
|
||||||
LoadMaterials();
|
LoadMaterials();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,6 +492,7 @@ namespace AZ
|
|||||||
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
|
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
|
||||||
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
|
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
|
||||||
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
|
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
|
||||||
|
ConvertAssetsForSerialization();
|
||||||
|
|
||||||
if (materialAssignment.RequiresLoading())
|
if (materialAssignment.RequiresLoading())
|
||||||
{
|
{
|
||||||
@@ -586,6 +590,7 @@ namespace AZ
|
|||||||
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
|
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
|
||||||
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
|
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
|
||||||
materialAssignment.m_propertyOverrides = propertyOverrides;
|
materialAssignment.m_propertyOverrides = propertyOverrides;
|
||||||
|
ConvertAssetsForSerialization();
|
||||||
|
|
||||||
if (materialAssignment.RequiresLoading())
|
if (materialAssignment.RequiresLoading())
|
||||||
{
|
{
|
||||||
@@ -667,5 +672,33 @@ namespace AZ
|
|||||||
TickBus::Handler::BusConnect();
|
TickBus::Handler::BusConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialComponentController::ConvertAssetsForSerialization()
|
||||||
|
{
|
||||||
|
for (auto& materialAssignmentPair : m_configuration.m_materials)
|
||||||
|
{
|
||||||
|
MaterialAssignment& materialAssignment = materialAssignmentPair.second;
|
||||||
|
for (auto& propertyPair : materialAssignment.m_propertyOverrides)
|
||||||
|
{
|
||||||
|
auto& value = propertyPair.second;
|
||||||
|
if (value.is<AZ::Data::Asset<AZ::Data::AssetData>>())
|
||||||
|
{
|
||||||
|
value = AZStd::any_cast<AZ::Data::Asset<AZ::Data::AssetData>>(value).GetId();
|
||||||
|
}
|
||||||
|
else if (value.is<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>())
|
||||||
|
{
|
||||||
|
value = AZStd::any_cast<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(value).GetId();
|
||||||
|
}
|
||||||
|
else if (value.is<AZ::Data::Asset<AZ::RPI::ImageAsset>>())
|
||||||
|
{
|
||||||
|
value = AZStd::any_cast<AZ::Data::Asset<AZ::RPI::ImageAsset>>(value).GetId();
|
||||||
|
}
|
||||||
|
else if (value.is<AZ::Data::Instance<AZ::RPI::Image>>())
|
||||||
|
{
|
||||||
|
value = AZStd::any_cast<AZ::Data::Instance<AZ::RPI::Image>>(value)->GetAssetId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace Render
|
} // namespace Render
|
||||||
} // namespace AZ
|
} // namespace AZ
|
||||||
|
|||||||
+5
@@ -99,6 +99,11 @@ namespace AZ
|
|||||||
//! Queue material instance recreation notifiucations until tick
|
//! Queue material instance recreation notifiucations until tick
|
||||||
void QueueMaterialUpdateNotification();
|
void QueueMaterialUpdateNotification();
|
||||||
|
|
||||||
|
//! Converts property overrides storing image asset references into asset IDs. This addresses a problem where image property
|
||||||
|
//! overrides are lost during prefab serialization and patching. This suboptimal function will be removed once the underlying
|
||||||
|
//! problem is resolved.
|
||||||
|
void ConvertAssetsForSerialization();
|
||||||
|
|
||||||
EntityId m_entityId;
|
EntityId m_entityId;
|
||||||
MaterialComponentConfig m_configuration;
|
MaterialComponentConfig m_configuration;
|
||||||
AZStd::unordered_set<MaterialAssignmentId> m_materialsWithDirtyProperties;
|
AZStd::unordered_set<MaterialAssignmentId> m_materialsWithDirtyProperties;
|
||||||
|
|||||||
+11
-1
@@ -11,6 +11,9 @@
|
|||||||
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
|
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
|
||||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||||
#include <AzCore/StringFunc/StringFunc.h>
|
#include <AzCore/StringFunc/StringFunc.h>
|
||||||
|
#include <Atom/RPI.Public/ViewportContextManager.h>
|
||||||
|
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||||
|
#include <Atom/RPI.Public/Base.h>
|
||||||
|
|
||||||
namespace AZ
|
namespace AZ
|
||||||
{
|
{
|
||||||
@@ -199,7 +202,14 @@ namespace AZ
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* LutAttachment = "LutOutput";
|
const char* LutAttachment = "LutOutput";
|
||||||
const AZStd::vector<AZStd::string> LutGenerationPassHierarchy{ "LutGenerationPass" };
|
auto renderPipelineName = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()
|
||||||
|
->GetDefaultViewportContext()
|
||||||
|
->GetCurrentPipeline()
|
||||||
|
->GetId();
|
||||||
|
const AZStd::vector<AZStd::string> LutGenerationPassHierarchy{
|
||||||
|
renderPipelineName.GetCStr(),
|
||||||
|
"LutGenerationPass"
|
||||||
|
};
|
||||||
|
|
||||||
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
"AssetProcessor": {
|
"AssetProcessor": {
|
||||||
"Settings": {
|
"Settings": {
|
||||||
"Exclude AudioProject": {
|
"Exclude AudioProject": {
|
||||||
"pattern": ".*\\\\/Sounds\\\\/.+_project.*"
|
"pattern": "(^|.+/)Sounds/.+_project.*"
|
||||||
},
|
},
|
||||||
"Exclude AudioTemp": {
|
"Exclude AudioTemp": {
|
||||||
"pattern": ".*\\\\/Sounds\\\\/.+\\\\.(txt|xml|dat)"
|
"pattern": "(^|.+/)Sounds/.+\\\\.(txt|xml|dat)"
|
||||||
},
|
},
|
||||||
"RC audio": {
|
"RC audio": {
|
||||||
"pattern": ".*\\\\.(wav|pcm)",
|
"pattern": ".*\\\\.(wav|pcm)",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"RC blastmaterial": {
|
"RC blastmaterial": {
|
||||||
"glob": "*.blastmaterial",
|
"glob": "*.blastmaterial",
|
||||||
"params": "copy",
|
"params": "copy",
|
||||||
|
"critical": true,
|
||||||
"productAssetType": "{55F38C86-0767-4E7F-830A-A4BF624BE4DA}"
|
"productAssetType": "{55F38C86-0767-4E7F-830A-A4BF624BE4DA}"
|
||||||
},
|
},
|
||||||
"RC blastconfiguration": {
|
"RC blastconfiguration": {
|
||||||
|
|||||||
+26
-18
@@ -91,17 +91,19 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralNodeTitleComponent::SetTitle(const AZStd::string& title)
|
void GeneralNodeTitleComponent::SetDetails(const AZStd::string& title, const AZStd::string& subtitle)
|
||||||
{
|
{
|
||||||
m_title.SetFallback(title);
|
m_title = title;
|
||||||
|
m_subTitle = subtitle;
|
||||||
|
|
||||||
if (m_generalNodeTitleWidget)
|
if (m_generalNodeTitleWidget)
|
||||||
{
|
{
|
||||||
m_generalNodeTitleWidget->SetTitle(title);
|
m_generalNodeTitleWidget->SetDetails(title, subtitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralNodeTitleComponent::SetTranslationKeyedTitle(const TranslationKeyedString& title)
|
void GeneralNodeTitleComponent::SetTitle(const AZStd::string& title)
|
||||||
{
|
{
|
||||||
m_title = title;
|
m_title = title;
|
||||||
|
|
||||||
@@ -113,20 +115,10 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
AZStd::string GeneralNodeTitleComponent::GetTitle() const
|
AZStd::string GeneralNodeTitleComponent::GetTitle() const
|
||||||
{
|
{
|
||||||
return m_title.GetDisplayString();
|
return m_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralNodeTitleComponent::SetSubTitle(const AZStd::string& subtitle)
|
void GeneralNodeTitleComponent::SetSubTitle(const AZStd::string& subtitle)
|
||||||
{
|
|
||||||
m_subTitle.SetFallback(subtitle);
|
|
||||||
|
|
||||||
if (m_generalNodeTitleWidget)
|
|
||||||
{
|
|
||||||
m_generalNodeTitleWidget->SetSubTitle(subtitle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralNodeTitleComponent::SetTranslationKeyedSubTitle(const TranslationKeyedString& subtitle)
|
|
||||||
{
|
{
|
||||||
m_subTitle = subtitle;
|
m_subTitle = subtitle;
|
||||||
|
|
||||||
@@ -138,7 +130,7 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
AZStd::string GeneralNodeTitleComponent::GetSubTitle() const
|
AZStd::string GeneralNodeTitleComponent::GetSubTitle() const
|
||||||
{
|
{
|
||||||
return m_subTitle.GetDisplayString();
|
return m_subTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
QGraphicsWidget* GeneralNodeTitleComponent::GetGraphicsWidget()
|
QGraphicsWidget* GeneralNodeTitleComponent::GetGraphicsWidget()
|
||||||
@@ -270,7 +262,23 @@ namespace GraphCanvas
|
|||||||
SceneNotificationBus::Handler::BusDisconnect();
|
SceneNotificationBus::Handler::BusDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralNodeTitleGraphicsWidget::SetTitle(const TranslationKeyedString& title)
|
void GeneralNodeTitleGraphicsWidget::SetDetails(const AZStd::string& title, const AZStd::string& subtitle)
|
||||||
|
{
|
||||||
|
bool updateLayout = false;
|
||||||
|
if (m_titleWidget)
|
||||||
|
{
|
||||||
|
m_titleWidget->SetLabel(title);
|
||||||
|
updateLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_subTitleWidget)
|
||||||
|
{
|
||||||
|
m_subTitleWidget->SetLabel(subtitle);
|
||||||
|
updateLayout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralNodeTitleGraphicsWidget::SetTitle(const AZStd::string& title)
|
||||||
{
|
{
|
||||||
if (m_titleWidget)
|
if (m_titleWidget)
|
||||||
{
|
{
|
||||||
@@ -279,7 +287,7 @@ namespace GraphCanvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralNodeTitleGraphicsWidget::SetSubTitle(const TranslationKeyedString& subtitle)
|
void GeneralNodeTitleGraphicsWidget::SetSubTitle(const AZStd::string& subtitle)
|
||||||
{
|
{
|
||||||
if (m_subTitleWidget)
|
if (m_subTitleWidget)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <GraphCanvas/Components/StyleBus.h>
|
#include <GraphCanvas/Components/StyleBus.h>
|
||||||
#include <GraphCanvas/Components/VisualBus.h>
|
#include <GraphCanvas/Components/VisualBus.h>
|
||||||
#include <GraphCanvas/Types/EntitySaveData.h>
|
#include <GraphCanvas/Types/EntitySaveData.h>
|
||||||
#include <GraphCanvas/Types/TranslationTypes.h>
|
|
||||||
#include <Widgets/GraphCanvasLabel.h>
|
#include <Widgets/GraphCanvasLabel.h>
|
||||||
|
|
||||||
namespace GraphCanvas
|
namespace GraphCanvas
|
||||||
@@ -68,12 +67,11 @@ namespace GraphCanvas
|
|||||||
////
|
////
|
||||||
|
|
||||||
// NodeTitleRequestBus
|
// NodeTitleRequestBus
|
||||||
|
void SetDetails(const AZStd::string& title, const AZStd::string& subtitle) override;
|
||||||
void SetTitle(const AZStd::string& title) override;
|
void SetTitle(const AZStd::string& title) override;
|
||||||
void SetTranslationKeyedTitle(const TranslationKeyedString& title) override;
|
|
||||||
AZStd::string GetTitle() const override;
|
AZStd::string GetTitle() const override;
|
||||||
|
|
||||||
void SetSubTitle(const AZStd::string& subtitle) override;
|
void SetSubTitle(const AZStd::string& subtitle) override;
|
||||||
void SetTranslationKeyedSubTitle(const TranslationKeyedString& subtitle) override;
|
|
||||||
AZStd::string GetSubTitle() const override;
|
AZStd::string GetSubTitle() const override;
|
||||||
|
|
||||||
QGraphicsWidget* GetGraphicsWidget() override;
|
QGraphicsWidget* GetGraphicsWidget() override;
|
||||||
@@ -96,8 +94,8 @@ namespace GraphCanvas
|
|||||||
private:
|
private:
|
||||||
GeneralNodeTitleComponent(const GeneralNodeTitleComponent&) = delete;
|
GeneralNodeTitleComponent(const GeneralNodeTitleComponent&) = delete;
|
||||||
|
|
||||||
TranslationKeyedString m_title;
|
AZStd::string m_title;
|
||||||
TranslationKeyedString m_subTitle;
|
AZStd::string m_subTitle;
|
||||||
|
|
||||||
AZStd::string m_basePalette;
|
AZStd::string m_basePalette;
|
||||||
|
|
||||||
@@ -123,9 +121,10 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
void Activate();
|
void Activate();
|
||||||
void Deactivate();
|
void Deactivate();
|
||||||
|
|
||||||
void SetTitle(const TranslationKeyedString& title);
|
void SetDetails(const AZStd::string& title, const AZStd::string& subtitle);
|
||||||
void SetSubTitle(const TranslationKeyedString& subtitle);
|
void SetTitle(const AZStd::string& title);
|
||||||
|
void SetSubTitle(const AZStd::string& subtitle);
|
||||||
|
|
||||||
void SetPaletteOverride(AZStd::string_view paletteOverride);
|
void SetPaletteOverride(AZStd::string_view paletteOverride);
|
||||||
void SetPaletteOverride(const AZ::Uuid& uuid);
|
void SetPaletteOverride(const AZ::Uuid& uuid);
|
||||||
|
|||||||
@@ -1007,20 +1007,16 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
if (!configuration.m_name.empty())
|
if (!configuration.m_name.empty())
|
||||||
{
|
{
|
||||||
cloneConfiguration->m_name.Clear();
|
cloneConfiguration->m_name = configuration.m_name;
|
||||||
cloneConfiguration->m_name.SetFallback(configuration.m_name);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AZStd::string nodeTitle;
|
AZStd::string nodeTitle;
|
||||||
NodeTitleRequestBus::EventResult(nodeTitle, configuration.m_targetEndpoint.GetNodeId(), &NodeTitleRequests::GetTitle);
|
NodeTitleRequestBus::EventResult(nodeTitle, configuration.m_targetEndpoint.GetNodeId(), &NodeTitleRequests::GetTitle);
|
||||||
|
|
||||||
AZStd::string displayName = AZStd::string::format("%s:%s", nodeTitle.c_str(), cloneConfiguration->m_name.GetDisplayString().c_str());
|
AZStd::string displayName = AZStd::string::format("%s:%s", nodeTitle.c_str(), cloneConfiguration->m_name.c_str());
|
||||||
|
|
||||||
// Gain some context. Lost the ability to refresh the strings.
|
cloneConfiguration->m_name = displayName;
|
||||||
// Should be fixable once we get an actual use case for this setup.
|
|
||||||
cloneConfiguration->m_name.Clear();
|
|
||||||
cloneConfiguration->m_name.SetFallback(displayName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Entity* slotEntity = nullptr;
|
AZ::Entity* slotEntity = nullptr;
|
||||||
|
|||||||
@@ -315,12 +315,6 @@ namespace GraphCanvas
|
|||||||
NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnTooltipChanged, m_configuration.GetTooltip());
|
NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnTooltipChanged, m_configuration.GetTooltip());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeComponent::SetTranslationKeyedTooltip(const TranslationKeyedString& tooltip)
|
|
||||||
{
|
|
||||||
m_configuration.SetTooltip(tooltip.GetDisplayString());
|
|
||||||
NodeNotificationBus::Event(GetEntityId(), &NodeNotifications::OnTooltipChanged, m_configuration.GetTooltip());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeComponent::AddSlot(const AZ::EntityId& slotId)
|
void NodeComponent::AddSlot(const AZ::EntityId& slotId)
|
||||||
{
|
{
|
||||||
AZ_Assert(slotId.IsValid(), "Slot entity (ID: %s) is not valid!", slotId.ToString().data());
|
AZ_Assert(slotId.IsValid(), "Slot entity (ID: %s) is not valid!", slotId.ToString().data());
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
// NodeRequestBus
|
// NodeRequestBus
|
||||||
void SetTooltip(const AZStd::string& tooltip) override;
|
void SetTooltip(const AZStd::string& tooltip) override;
|
||||||
void SetTranslationKeyedTooltip(const TranslationKeyedString& tooltip) override;
|
|
||||||
const AZStd::string GetTooltip() const override { return m_configuration.GetTooltip(); }
|
const AZStd::string GetTooltip() const override { return m_configuration.GetTooltip(); }
|
||||||
|
|
||||||
void SetShowInOutliner(bool showInOutliner) override { m_configuration.SetShowInOutliner(showInOutliner); }
|
void SetShowInOutliner(bool showInOutliner) override { m_configuration.SetShowInOutliner(showInOutliner); }
|
||||||
|
|||||||
@@ -669,6 +669,7 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
GeometryNotificationBus::Handler::BusDisconnect();
|
GeometryNotificationBus::Handler::BusDisconnect();
|
||||||
SceneNotificationBus::Handler::BusDisconnect();
|
SceneNotificationBus::Handler::BusDisconnect();
|
||||||
|
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GestureSceneHelper::TrackElement(const AZ::EntityId& elementId)
|
void GestureSceneHelper::TrackElement(const AZ::EntityId& elementId)
|
||||||
|
|||||||
@@ -337,12 +337,9 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
m_connectionType = slotRequests->GetConnectionType();
|
m_connectionType = slotRequests->GetConnectionType();
|
||||||
|
|
||||||
TranslationKeyedString slotName = slotRequests->GetTranslationKeyedName();
|
m_slotText->SetLabel(slotRequests->GetName());
|
||||||
|
|
||||||
m_slotText->SetLabel(slotName);
|
OnTooltipChanged(slotRequests->GetTooltip());
|
||||||
|
|
||||||
TranslationKeyedString toolTip = slotRequests->GetTranslationKeyedTooltip();
|
|
||||||
OnTooltipChanged(toolTip);
|
|
||||||
|
|
||||||
const SlotConfiguration& configuration = slotRequests->GetSlotConfiguration();
|
const SlotConfiguration& configuration = slotRequests->GetSlotConfiguration();
|
||||||
|
|
||||||
@@ -393,12 +390,12 @@ namespace GraphCanvas
|
|||||||
AZ::SystemTickBus::Handler::BusConnect();
|
AZ::SystemTickBus::Handler::BusConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataSlotLayout::OnNameChanged(const TranslationKeyedString& name)
|
void DataSlotLayout::OnNameChanged(const AZStd::string& name)
|
||||||
{
|
{
|
||||||
m_slotText->SetLabel(name);
|
m_slotText->SetLabel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataSlotLayout::OnTooltipChanged(const TranslationKeyedString& tooltip)
|
void DataSlotLayout::OnTooltipChanged(const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
AZ::Uuid dataType;
|
AZ::Uuid dataType;
|
||||||
DataSlotRequestBus::EventResult(dataType, m_owner.GetEntityId(), &DataSlotRequests::GetDataTypeId);
|
DataSlotRequestBus::EventResult(dataType, m_owner.GetEntityId(), &DataSlotRequests::GetDataTypeId);
|
||||||
@@ -406,7 +403,7 @@ namespace GraphCanvas
|
|||||||
AZStd::string typeString;
|
AZStd::string typeString;
|
||||||
GraphModelRequestBus::EventResult(typeString, GetSceneId(), &GraphModelRequests::GetDataTypeString, dataType);
|
GraphModelRequestBus::EventResult(typeString, GetSceneId(), &GraphModelRequests::GetDataTypeString, dataType);
|
||||||
|
|
||||||
AZStd::string displayText = tooltip.GetDisplayString();
|
AZStd::string displayText = tooltip;
|
||||||
|
|
||||||
if (!typeString.empty())
|
if (!typeString.empty())
|
||||||
{
|
{
|
||||||
@@ -486,7 +483,7 @@ namespace GraphCanvas
|
|||||||
if (!iconPath.empty())
|
if (!iconPath.empty())
|
||||||
{
|
{
|
||||||
m_textDecoration = new GraphCanvasLabel();
|
m_textDecoration = new GraphCanvasLabel();
|
||||||
m_textDecoration->SetLabel(iconPath, "", "");
|
m_textDecoration->SetLabel(iconPath);
|
||||||
m_textDecoration->setToolTip(toolTip.c_str());
|
m_textDecoration->setToolTip(toolTip.c_str());
|
||||||
|
|
||||||
ApplyTextStyle(m_textDecoration);
|
ApplyTextStyle(m_textDecoration);
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ namespace GraphCanvas
|
|||||||
// SlotNotificationBus
|
// SlotNotificationBus
|
||||||
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
||||||
|
|
||||||
void OnNameChanged(const TranslationKeyedString&) override;
|
void OnNameChanged(const AZStd::string&) override;
|
||||||
void OnTooltipChanged(const TranslationKeyedString&) override;
|
void OnTooltipChanged(const AZStd::string&) override;
|
||||||
////
|
////
|
||||||
|
|
||||||
// StyleNotificationBus
|
// StyleNotificationBus
|
||||||
|
|||||||
+7
-14
@@ -58,13 +58,8 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
m_connectionType = slotRequests->GetConnectionType();
|
m_connectionType = slotRequests->GetConnectionType();
|
||||||
|
|
||||||
TranslationKeyedString slotName = slotRequests->GetTranslationKeyedName();
|
m_slotText->SetLabel(slotRequests->GetName());
|
||||||
|
OnTooltipChanged(slotRequests->GetTooltip());
|
||||||
m_slotText->SetLabel(slotName);
|
|
||||||
|
|
||||||
TranslationKeyedString toolTip = slotRequests->GetTranslationKeyedTooltip();
|
|
||||||
|
|
||||||
OnTooltipChanged(toolTip);
|
|
||||||
|
|
||||||
const SlotConfiguration& configuration = slotRequests->GetSlotConfiguration();
|
const SlotConfiguration& configuration = slotRequests->GetSlotConfiguration();
|
||||||
|
|
||||||
@@ -88,17 +83,15 @@ namespace GraphCanvas
|
|||||||
OnStyleChanged();
|
OnStyleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecutionSlotLayout::OnNameChanged(const TranslationKeyedString& name)
|
void ExecutionSlotLayout::OnNameChanged(const AZStd::string& name)
|
||||||
{
|
{
|
||||||
m_slotText->SetLabel(name);
|
m_slotText->SetLabel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecutionSlotLayout::OnTooltipChanged(const TranslationKeyedString& tooltip)
|
void ExecutionSlotLayout::OnTooltipChanged(const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
AZStd::string displayText = tooltip.GetDisplayString();
|
m_slotConnectionPin->setToolTip(tooltip.c_str());
|
||||||
|
m_slotText->setToolTip(tooltip.c_str());
|
||||||
m_slotConnectionPin->setToolTip(displayText.c_str());
|
|
||||||
m_slotText->setToolTip(displayText.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecutionSlotLayout::OnStyleChanged()
|
void ExecutionSlotLayout::OnStyleChanged()
|
||||||
@@ -132,7 +125,7 @@ namespace GraphCanvas
|
|||||||
if (!textDecoration.empty())
|
if (!textDecoration.empty())
|
||||||
{
|
{
|
||||||
m_textDecoration = new GraphCanvasLabel();
|
m_textDecoration = new GraphCanvasLabel();
|
||||||
m_textDecoration->SetLabel(textDecoration, "", "");
|
m_textDecoration->SetLabel(textDecoration);
|
||||||
m_textDecoration->setToolTip(toolTip.c_str());
|
m_textDecoration->setToolTip(toolTip.c_str());
|
||||||
|
|
||||||
ApplyTextStyle(m_textDecoration);
|
ApplyTextStyle(m_textDecoration);
|
||||||
|
|||||||
+2
-2
@@ -46,8 +46,8 @@ namespace GraphCanvas
|
|||||||
// SlotNotificationBus
|
// SlotNotificationBus
|
||||||
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
||||||
|
|
||||||
void OnNameChanged(const TranslationKeyedString& name) override;
|
void OnNameChanged(const AZStd::string& name) override;
|
||||||
void OnTooltipChanged(const TranslationKeyedString& tooltip) override;
|
void OnTooltipChanged(const AZStd::string& tooltip) override;
|
||||||
////
|
////
|
||||||
|
|
||||||
// StyleNotificationBus
|
// StyleNotificationBus
|
||||||
|
|||||||
+8
-10
@@ -119,13 +119,13 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
SlotRequestBus::EventResult(m_connectionType, m_owner.GetEntityId(), &SlotRequests::GetConnectionType);
|
SlotRequestBus::EventResult(m_connectionType, m_owner.GetEntityId(), &SlotRequests::GetConnectionType);
|
||||||
|
|
||||||
TranslationKeyedString slotName;
|
AZStd::string slotName;
|
||||||
SlotRequestBus::EventResult(slotName, m_owner.GetEntityId(), &SlotRequests::GetTranslationKeyedName);
|
SlotRequestBus::EventResult(slotName, m_owner.GetEntityId(), &SlotRequests::GetName);
|
||||||
|
|
||||||
m_slotText->SetLabel(slotName);
|
m_slotText->SetLabel(slotName);
|
||||||
|
|
||||||
TranslationKeyedString toolTip;
|
AZStd::string toolTip;
|
||||||
SlotRequestBus::EventResult(toolTip, m_owner.GetEntityId(), &SlotRequests::GetTranslationKeyedTooltip);
|
SlotRequestBus::EventResult(toolTip, m_owner.GetEntityId(), &SlotRequests::GetTooltip);
|
||||||
|
|
||||||
OnTooltipChanged(toolTip);
|
OnTooltipChanged(toolTip);
|
||||||
|
|
||||||
@@ -151,17 +151,15 @@ namespace GraphCanvas
|
|||||||
OnStyleChanged();
|
OnStyleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtenderSlotLayout::OnNameChanged(const TranslationKeyedString& name)
|
void ExtenderSlotLayout::OnNameChanged(const AZStd::string& name)
|
||||||
{
|
{
|
||||||
m_slotText->SetLabel(name);
|
m_slotText->SetLabel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtenderSlotLayout::OnTooltipChanged(const TranslationKeyedString& tooltip)
|
void ExtenderSlotLayout::OnTooltipChanged(const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
AZStd::string displayText = tooltip.GetDisplayString();
|
m_slotConnectionPin->setToolTip(tooltip.c_str());
|
||||||
|
m_slotText->setToolTip(tooltip.c_str());
|
||||||
m_slotConnectionPin->setToolTip(displayText.c_str());
|
|
||||||
m_slotText->setToolTip(displayText.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtenderSlotLayout::OnStyleChanged()
|
void ExtenderSlotLayout::OnStyleChanged()
|
||||||
|
|||||||
+2
-2
@@ -48,8 +48,8 @@ namespace GraphCanvas
|
|||||||
// SlotNotificationBus
|
// SlotNotificationBus
|
||||||
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
||||||
|
|
||||||
void OnNameChanged(const TranslationKeyedString& name) override;
|
void OnNameChanged(const AZStd::string& name) override;
|
||||||
void OnTooltipChanged(const TranslationKeyedString& tooltip) override;
|
void OnTooltipChanged(const AZStd::string& tooltip) override;
|
||||||
////
|
////
|
||||||
|
|
||||||
// StyleNotificationBus
|
// StyleNotificationBus
|
||||||
|
|||||||
+3
-3
@@ -90,10 +90,10 @@ namespace GraphCanvas
|
|||||||
TryAndSetupSlot();
|
TryAndSetupSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertySlotLayout::OnTooltipChanged(const TranslationKeyedString& tooltip)
|
void PropertySlotLayout::OnTooltipChanged(const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
m_slotText->setToolTip(Tools::qStringFromUtf8(tooltip.GetDisplayString()));
|
m_slotText->setToolTip(Tools::qStringFromUtf8(tooltip));
|
||||||
m_nodePropertyDisplay->setToolTip(Tools::qStringFromUtf8(tooltip.GetDisplayString()));
|
m_nodePropertyDisplay->setToolTip(Tools::qStringFromUtf8(tooltip));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertySlotLayout::OnStyleChanged()
|
void PropertySlotLayout::OnStyleChanged()
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ namespace GraphCanvas
|
|||||||
// SlotNotificationBus
|
// SlotNotificationBus
|
||||||
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
void OnRegisteredToNode(const AZ::EntityId& nodeId) override;
|
||||||
|
|
||||||
void OnTooltipChanged(const TranslationKeyedString& tooltip) override;
|
void OnTooltipChanged(const AZStd::string& tooltip) override;
|
||||||
////
|
////
|
||||||
|
|
||||||
// StyleNotificationBus
|
// StyleNotificationBus
|
||||||
|
|||||||
@@ -91,14 +91,6 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
void SlotComponent::Activate()
|
void SlotComponent::Activate()
|
||||||
{
|
{
|
||||||
SetTranslationKeyedName(m_slotConfiguration.m_name);
|
|
||||||
|
|
||||||
// Default tooltip.
|
|
||||||
if (m_slotConfiguration.m_tooltip.empty())
|
|
||||||
{
|
|
||||||
SetTranslationKeyedTooltip(m_slotConfiguration.m_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
SlotRequestBus::Handler::BusConnect(GetEntityId());
|
SlotRequestBus::Handler::BusConnect(GetEntityId());
|
||||||
SceneMemberRequestBus::Handler::BusConnect(GetEntityId());
|
SceneMemberRequestBus::Handler::BusConnect(GetEntityId());
|
||||||
}
|
}
|
||||||
@@ -171,24 +163,6 @@ namespace GraphCanvas
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SlotComponent::SetName(const AZStd::string& name)
|
void SlotComponent::SetName(const AZStd::string& name)
|
||||||
{
|
|
||||||
if (name == m_slotConfiguration.m_name.GetDisplayString())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_slotConfiguration.m_name.SetFallback(name);
|
|
||||||
|
|
||||||
// Default tooltip.
|
|
||||||
if (m_slotConfiguration.m_tooltip.empty())
|
|
||||||
{
|
|
||||||
m_slotConfiguration.m_tooltip = m_slotConfiguration.m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnNameChanged, m_slotConfiguration.m_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlotComponent::SetTranslationKeyedName(const TranslationKeyedString& name)
|
|
||||||
{
|
{
|
||||||
if (name == m_slotConfiguration.m_name)
|
if (name == m_slotConfiguration.m_name)
|
||||||
{
|
{
|
||||||
@@ -206,25 +180,22 @@ namespace GraphCanvas
|
|||||||
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnNameChanged, m_slotConfiguration.m_name);
|
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnNameChanged, m_slotConfiguration.m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotComponent::SetTooltip(const AZStd::string& tooltip)
|
void SlotComponent::SetDetails(const AZStd::string& name, const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
if (tooltip == m_slotConfiguration.m_tooltip.GetDisplayString())
|
if (name != m_slotConfiguration.m_name)
|
||||||
{
|
{
|
||||||
return;
|
m_slotConfiguration.m_name = name;
|
||||||
|
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnNameChanged, m_slotConfiguration.m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_slotConfiguration.m_tooltip.SetFallback(tooltip);
|
if (tooltip != m_slotConfiguration.m_tooltip)
|
||||||
|
|
||||||
// Default tooltip.
|
|
||||||
if (m_slotConfiguration.m_tooltip.empty())
|
|
||||||
{
|
{
|
||||||
m_slotConfiguration.m_tooltip = m_slotConfiguration.m_name;
|
m_slotConfiguration.m_tooltip = tooltip;
|
||||||
|
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnTooltipChanged, m_slotConfiguration.m_tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
SlotNotificationBus::Event(GetEntityId(), &SlotNotifications::OnTooltipChanged, m_slotConfiguration.m_tooltip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotComponent::SetTranslationKeyedTooltip(const TranslationKeyedString& tooltip)
|
void SlotComponent::SetTooltip(const AZStd::string& tooltip)
|
||||||
{
|
{
|
||||||
if (tooltip == m_slotConfiguration.m_tooltip)
|
if (tooltip == m_slotConfiguration.m_tooltip)
|
||||||
{
|
{
|
||||||
@@ -521,8 +492,8 @@ namespace GraphCanvas
|
|||||||
{
|
{
|
||||||
slotConfiguration.m_connectionType = GetConnectionType();
|
slotConfiguration.m_connectionType = GetConnectionType();
|
||||||
|
|
||||||
slotConfiguration.m_name = GetTranslationKeyedName();
|
slotConfiguration.m_name = m_slotConfiguration.m_name;
|
||||||
slotConfiguration.m_tooltip = GetTranslationKeyedTooltip();
|
slotConfiguration.m_tooltip = m_slotConfiguration.m_tooltip;
|
||||||
|
|
||||||
slotConfiguration.m_slotGroup = GetSlotGroup();
|
slotConfiguration.m_slotGroup = GetSlotGroup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,18 +74,14 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
Endpoint GetEndpoint() const override;
|
Endpoint GetEndpoint() const override;
|
||||||
|
|
||||||
const AZStd::string GetName() const override { return m_slotConfiguration.m_name.GetDisplayString(); }
|
const AZStd::string GetName() const override { return m_slotConfiguration.m_name; }
|
||||||
void SetName(const AZStd::string& name) override;
|
void SetName(const AZStd::string& name) override;
|
||||||
|
|
||||||
TranslationKeyedString GetTranslationKeyedName() const override { return m_slotConfiguration.m_name; }
|
void SetDetails(const AZStd::string& name, const AZStd::string& tooltip) override;
|
||||||
void SetTranslationKeyedName(const TranslationKeyedString&) override;
|
|
||||||
|
|
||||||
const AZStd::string GetTooltip() const override { return m_slotConfiguration.m_tooltip.GetDisplayString(); }
|
const AZStd::string GetTooltip() const override { return m_slotConfiguration.m_tooltip; }
|
||||||
void SetTooltip(const AZStd::string& tooltip) override;
|
void SetTooltip(const AZStd::string& tooltip) override;
|
||||||
|
|
||||||
TranslationKeyedString GetTranslationKeyedTooltip() const override { return m_slotConfiguration.m_tooltip; }
|
|
||||||
void SetTranslationKeyedTooltip(const TranslationKeyedString&) override;
|
|
||||||
|
|
||||||
void DisplayProposedConnection(const AZ::EntityId& connectionId, const Endpoint& endpoint) override;
|
void DisplayProposedConnection(const AZ::EntityId& connectionId, const Endpoint& endpoint) override;
|
||||||
void RemoveProposedConnection(const AZ::EntityId& connectionId, const Endpoint& endpoint) override;
|
void RemoveProposedConnection(const AZ::EntityId& connectionId, const Endpoint& endpoint) override;
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@
|
|||||||
|
|
||||||
#include <GraphCanvas/Types/ConstructPresets.h>
|
#include <GraphCanvas/Types/ConstructPresets.h>
|
||||||
#include <GraphCanvas/Types/EntitySaveData.h>
|
#include <GraphCanvas/Types/EntitySaveData.h>
|
||||||
#include <GraphCanvas/Types/TranslationTypes.h>
|
|
||||||
|
|
||||||
#include <GraphCanvas/Widgets/GraphCanvasEditor/GraphCanvasAssetEditorMainWindow.h>
|
#include <GraphCanvas/Widgets/GraphCanvasEditor/GraphCanvasAssetEditorMainWindow.h>
|
||||||
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
|
#include <GraphCanvas/Widgets/GraphCanvasMimeEvent.h>
|
||||||
@@ -140,7 +139,6 @@ namespace GraphCanvas
|
|||||||
Styling::DefaultSelector::Reflect(serializeContext);
|
Styling::DefaultSelector::Reflect(serializeContext);
|
||||||
Styling::CompoundSelector::Reflect(serializeContext);
|
Styling::CompoundSelector::Reflect(serializeContext);
|
||||||
Styling::NestedSelector::Reflect(serializeContext);
|
Styling::NestedSelector::Reflect(serializeContext);
|
||||||
TranslationKeyedString::Reflect(serializeContext);
|
|
||||||
Styling::Style::Reflect(serializeContext);
|
Styling::Style::Reflect(serializeContext);
|
||||||
AssetEditorUserSettings::Reflect(serializeContext);
|
AssetEditorUserSettings::Reflect(serializeContext);
|
||||||
}
|
}
|
||||||
@@ -218,6 +216,9 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::RegisterSourceAssetType, azrtti_typeid<TranslationAsset>(), TranslationAsset::GetFileFilter());
|
AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::RegisterSourceAssetType, azrtti_typeid<TranslationAsset>(), TranslationAsset::GetFileFilter());
|
||||||
m_translationAssetWorker.Activate();
|
m_translationAssetWorker.Activate();
|
||||||
|
|
||||||
|
m_assetHandler = AZStd::make_unique<TranslationAssetHandler>();
|
||||||
|
m_assetHandler->Register();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,15 +377,27 @@ namespace GraphCanvas
|
|||||||
// Find any TranslationAsset files that may have translation database key/values
|
// Find any TranslationAsset files that may have translation database key/values
|
||||||
AZ::Data::AssetCatalogRequests::AssetEnumerationCB collectAssetsCb = [this](const AZ::Data::AssetId assetId, const AZ::Data::AssetInfo& assetInfo)
|
AZ::Data::AssetCatalogRequests::AssetEnumerationCB collectAssetsCb = [this](const AZ::Data::AssetId assetId, const AZ::Data::AssetInfo& assetInfo)
|
||||||
{
|
{
|
||||||
const auto assetType = azrtti_typeid<TranslationAsset>();
|
if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath, ".names", false))
|
||||||
if (assetInfo.m_assetType == assetType)
|
|
||||||
{
|
{
|
||||||
m_translationAssets.push_back(assetId);
|
m_translationAssets.push_back(assetId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_translationAssets.clear();
|
||||||
|
|
||||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, collectAssetsCb, postEnumerateCb);
|
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, collectAssetsCb, postEnumerateCb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphCanvasSystemComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
|
||||||
|
{
|
||||||
|
AZ::Data::AssetInfo assetInfo;
|
||||||
|
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
|
||||||
|
if (assetInfo.m_assetType == azrtti_typeid<TranslationAsset>())
|
||||||
|
{
|
||||||
|
GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::Restore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GraphCanvasSystemComponent::UnregisterAssetHandler()
|
void GraphCanvasSystemComponent::UnregisterAssetHandler()
|
||||||
{
|
{
|
||||||
if (m_assetHandler)
|
if (m_assetHandler)
|
||||||
@@ -405,7 +418,7 @@ namespace GraphCanvas
|
|||||||
for (const AZ::Data::AssetId& assetId : m_translationAssets)
|
for (const AZ::Data::AssetId& assetId : m_translationAssets)
|
||||||
{
|
{
|
||||||
AZ::Data::AssetBus::MultiHandler::BusConnect(assetId);
|
AZ::Data::AssetBus::MultiHandler::BusConnect(assetId);
|
||||||
AZ::Data::AssetManager::Instance().GetAsset<TranslationAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
|
AZ::Data::AssetManager::Instance().GetAsset<TranslationAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,10 @@ namespace GraphCanvas
|
|||||||
AZ::EntityId CreateVirtualChild(const AZ::EntityId& real, const AZStd::string& virtualChildElement) const override;
|
AZ::EntityId CreateVirtualChild(const AZ::EntityId& real, const AZStd::string& virtualChildElement) const override;
|
||||||
////
|
////
|
||||||
|
|
||||||
|
// AzFramework::AssetCatalogEventBus::Handler
|
||||||
void OnCatalogLoaded(const char* /*catalogFile*/) override;
|
void OnCatalogLoaded(const char* /*catalogFile*/) override;
|
||||||
|
void OnCatalogAssetChanged(const AZ::Data::AssetId&) override;
|
||||||
|
////
|
||||||
|
|
||||||
AZStd::unique_ptr<TranslationAssetHandler> m_assetHandler;
|
AZStd::unique_ptr<TranslationAssetHandler> m_assetHandler;
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ namespace GraphCanvas
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AZ_Error("TranslationAsset", false, "Serialization of the TranslationFormat failed for: %s", asset.GetHint().c_str());
|
AZ_Warning("TranslationAsset", false, "Serialization of the TranslationFormat failed for: %s", asset.GetHint().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ namespace GraphCanvas
|
|||||||
//!
|
//!
|
||||||
//! Requirements:
|
//! Requirements:
|
||||||
//! - Must have a top level array called "entries"
|
//! - Must have a top level array called "entries"
|
||||||
//! - Must provide a "key" element for any entry added
|
//! - Must provide a "base" element for any entry added
|
||||||
//!
|
//!
|
||||||
//! Example:
|
//! Example:
|
||||||
//!
|
//!
|
||||||
//! {
|
//! {
|
||||||
//! "entries": [
|
//! "entries": [
|
||||||
//! {
|
//! {
|
||||||
//! "key": "Globals",
|
//! "base": "Globals",
|
||||||
//! "details": {
|
//! "details": {
|
||||||
//! "name": "My Name",
|
//! "name": "My Name",
|
||||||
//! "tooltip": "My Tooltip"
|
//! "tooltip": "My Tooltip"
|
||||||
@@ -90,21 +90,21 @@ namespace GraphCanvas
|
|||||||
//! Globals.details.somearray.0.name
|
//! Globals.details.somearray.0.name
|
||||||
//! Globals.details.somearray.1.name
|
//! Globals.details.somearray.1.name
|
||||||
//!
|
//!
|
||||||
//! There is one important aspect however, if an element in an array has a "key" value, the value of this key
|
//! There is one important aspect however, if an element in an array has a "base" value, the value of this key
|
||||||
//! will replace the index. This is useful when the index and/or ordering of an entry is not relevant or may
|
//! will replace the index. This is useful when the index and/or ordering of an entry is not relevant or may
|
||||||
//! change.
|
//! change.
|
||||||
//!
|
//!
|
||||||
//! "somearray": [ {
|
//! "somearray": [ {
|
||||||
//! "name": "First one"
|
//! "name": "First one"
|
||||||
//! "key": "a_key"
|
//! "base": "a_key"
|
||||||
//! }, {
|
//! }, {
|
||||||
//! "name": "Second one",
|
//! "name": "Second one",
|
||||||
//! "key": "b_key"
|
//! "base": "b_key"
|
||||||
//! } ]
|
//! } ]
|
||||||
//!
|
//!
|
||||||
//! Globals.details.somearray.0.key == "a_key"
|
//! Globals.details.somearray.0.base == "a_key"
|
||||||
//! Globals.details.somearray.0.name == "First one"
|
//! Globals.details.somearray.0.name == "First one"
|
||||||
//! Globals.details.somearray.1.key == "b_key"
|
//! Globals.details.somearray.1.base == "b_key"
|
||||||
//! Globals.details.somearray.1.name == "Second one"
|
//! Globals.details.somearray.1.name == "Second one"
|
||||||
//!
|
//!
|
||||||
class TranslationAssetHandler
|
class TranslationAssetHandler
|
||||||
|
|||||||
@@ -30,16 +30,7 @@ namespace GraphCanvas
|
|||||||
void TranslationAssetWorker::Activate()
|
void TranslationAssetWorker::Activate()
|
||||||
{
|
{
|
||||||
// Use AssetCatalog service to register ScriptCanvas asset type and extension
|
// Use AssetCatalog service to register ScriptCanvas asset type and extension
|
||||||
AZ::Data::AssetType assetType(azrtti_typeid<TranslationAsset>());
|
|
||||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddAssetType, assetType);
|
|
||||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::EnableCatalogForAsset, assetType);
|
|
||||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, TranslationAsset::GetFileFilter());
|
|
||||||
|
|
||||||
m_assetHandler = AZStd::make_unique<TranslationAssetHandler>();
|
m_assetHandler = AZStd::make_unique<TranslationAssetHandler>();
|
||||||
if (!AZ::Data::AssetManager::Instance().GetHandler(assetType))
|
|
||||||
{
|
|
||||||
AZ::Data::AssetManager::Instance().RegisterHandler(m_assetHandler.get(), assetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetBuilderSDK::AssetBuilderCommandBus::Handler::BusConnect(GetUUID());
|
AssetBuilderSDK::AssetBuilderCommandBus::Handler::BusConnect(GetUUID());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,10 @@
|
|||||||
|
|
||||||
#include "TranslationAsset.h"
|
#include "TranslationAsset.h"
|
||||||
|
|
||||||
|
#include <AzCore/std/string/conversions.h>
|
||||||
#include <AzCore/StringFunc/StringFunc.h>
|
#include <AzCore/StringFunc/StringFunc.h>
|
||||||
|
|
||||||
|
|
||||||
namespace GraphCanvas
|
namespace GraphCanvas
|
||||||
{
|
{
|
||||||
namespace Translation
|
namespace Translation
|
||||||
@@ -88,10 +90,16 @@ namespace GraphCanvas
|
|||||||
static AZStd::string Sanitize(const AZStd::string& text)
|
static AZStd::string Sanitize(const AZStd::string& text)
|
||||||
{
|
{
|
||||||
AZStd::string result = text;
|
AZStd::string result = text;
|
||||||
|
AZ::StringFunc::Replace(result, "*", "x");
|
||||||
|
AZ::StringFunc::Replace(result, "(", "_");
|
||||||
|
AZ::StringFunc::Replace(result, ")", "_");
|
||||||
|
AZ::StringFunc::Replace(result, "{", "_");
|
||||||
|
AZ::StringFunc::Replace(result, "}", "_");
|
||||||
AZ::StringFunc::Replace(result, ":", "_");
|
AZ::StringFunc::Replace(result, ":", "_");
|
||||||
AZ::StringFunc::Replace(result, "<", "_");
|
AZ::StringFunc::Replace(result, "<", "_");
|
||||||
AZ::StringFunc::Replace(result, ",", "_");
|
AZ::StringFunc::Replace(result, ",", "_");
|
||||||
AZ::StringFunc::Replace(result, ">", " ");
|
AZ::StringFunc::Replace(result, ">", " ");
|
||||||
|
AZ::StringFunc::Replace(result, "/", "");
|
||||||
AZ::StringFunc::Strip(result, " ");
|
AZ::StringFunc::Strip(result, " ");
|
||||||
AZ::StringFunc::Path::Normalize(result);
|
AZ::StringFunc::Path::Normalize(result);
|
||||||
return result;
|
return result;
|
||||||
@@ -117,32 +125,32 @@ namespace GraphCanvas
|
|||||||
virtual bool HasKey(const AZStd::string& /*key*/) { return false; }
|
virtual bool HasKey(const AZStd::string& /*key*/) { return false; }
|
||||||
|
|
||||||
//! Returns the text value for a given key
|
//! Returns the text value for a given key
|
||||||
virtual const char* Get(const AZStd::string& /*key*/) { return nullptr; }
|
virtual bool Get(const AZStd::string& /*key*/, AZStd::string& /*value*/) { return false; }
|
||||||
|
|
||||||
struct Details
|
struct Details
|
||||||
{
|
{
|
||||||
AZStd::string Name;
|
AZStd::string m_name;
|
||||||
AZStd::string Tooltip;
|
AZStd::string m_tooltip;
|
||||||
AZStd::string Category;
|
AZStd::string m_category;
|
||||||
AZStd::string Subtitle;
|
AZStd::string m_subtitle;
|
||||||
|
|
||||||
bool Valid = false;
|
bool m_valid = false;
|
||||||
|
|
||||||
Details() = default;
|
Details() = default;
|
||||||
|
|
||||||
Details(const Details& rhs)
|
Details(const Details& rhs)
|
||||||
{
|
{
|
||||||
Name = rhs.Name;
|
m_name = rhs.m_name;
|
||||||
Tooltip = rhs.Tooltip;
|
m_tooltip = rhs.m_tooltip;
|
||||||
Subtitle = rhs.Subtitle;
|
m_category = rhs.m_category;
|
||||||
Category = rhs.Category;
|
m_subtitle = rhs.m_subtitle;
|
||||||
Valid = rhs.Valid;
|
m_valid = rhs.m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Details(const char* name, const char* tooltip, const char* subtitle, const char* category)
|
Details(const char* name, const char* tooltip, const char* subtitle, const char* category)
|
||||||
: Name(name), Tooltip(tooltip), Subtitle(subtitle), Category(category)
|
: m_name(name), m_tooltip(tooltip), m_subtitle(subtitle), m_category(category)
|
||||||
{
|
{
|
||||||
Valid = !Name.empty();
|
m_valid = !m_name.empty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,7 +158,7 @@ namespace GraphCanvas
|
|||||||
virtual bool Add(const TranslationFormat& /*translationFormat*/) { return false; }
|
virtual bool Add(const TranslationFormat& /*translationFormat*/) { return false; }
|
||||||
|
|
||||||
//! Get the details associated with a given key (assumes they are within a "details" object)
|
//! Get the details associated with a given key (assumes they are within a "details" object)
|
||||||
virtual Details GetDetails(const AZStd::string& /*key*/) { return Details(); }
|
virtual Details GetDetails(const AZStd::string& /*key*/, const Details& /*fallbackDetails*/) { return Details(); }
|
||||||
|
|
||||||
//! Generates the source JSON assets for all reflected elements
|
//! Generates the source JSON assets for all reflected elements
|
||||||
virtual void GenerateSourceAssets() {}
|
virtual void GenerateSourceAssets() {}
|
||||||
|
|||||||
@@ -104,35 +104,49 @@ namespace GraphCanvas
|
|||||||
return m_database.find(key) != m_database.end();
|
return m_database.find(key) != m_database.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphCanvas::TranslationRequests::Details TranslationDatabase::GetDetails(const AZStd::string& key)
|
GraphCanvas::TranslationRequests::Details TranslationDatabase::GetDetails(const AZStd::string& key, const Details& fallbackDetails)
|
||||||
{
|
{
|
||||||
const char* name = Get(key + ".name");
|
Details details;
|
||||||
const char* tooltip = Get(key + ".tooltip");
|
if (!Get(key + ".name", details.m_name))
|
||||||
const char* subtitle = Get(key + ".subtitle");
|
|
||||||
const char* category = Get(key + ".category");
|
|
||||||
|
|
||||||
static bool s_traceMissingItems = true;
|
|
||||||
if (s_traceMissingItems)
|
|
||||||
{
|
{
|
||||||
AZ_TracePrintf("GraphCanvas", AZStd::string::format("Value (name) not found for key: %s", key.c_str()).c_str());
|
details.m_name = fallbackDetails.m_name;
|
||||||
AZ_TracePrintf("GraphCanvas", AZStd::string::format("Value (tooltip) not found for key: %s", key.c_str()).c_str());
|
|
||||||
AZ_TracePrintf("GraphCanvas", AZStd::string::format("Value (subtitle) not found for key: %s", key.c_str()).c_str());
|
|
||||||
AZ_TracePrintf("GraphCanvas", AZStd::string::format("Value (category) not found for key: %s", key.c_str()).c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Details(name ? name : "", tooltip ? tooltip : "", subtitle ? subtitle : "", category ? category : "");
|
if (!Get(key + ".tooltip", details.m_tooltip))
|
||||||
|
{
|
||||||
|
details.m_tooltip = fallbackDetails.m_tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Get(key + ".subtitle", details.m_subtitle))
|
||||||
|
{
|
||||||
|
details.m_subtitle = fallbackDetails.m_subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Get(key + ".category", details.m_category))
|
||||||
|
{
|
||||||
|
details.m_category = fallbackDetails.m_category;
|
||||||
|
}
|
||||||
|
|
||||||
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* TranslationDatabase::Get(const AZStd::string& key)
|
bool TranslationDatabase::Get(const AZStd::string& key, AZStd::string& value)
|
||||||
{
|
{
|
||||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
if (m_database.find(key) != m_database.end())
|
if (m_database.find(key) != m_database.end())
|
||||||
{
|
{
|
||||||
return m_database[key].c_str();
|
value = m_database[key];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
static bool s_traceMissingItems = false;
|
||||||
|
if (s_traceMissingItems)
|
||||||
|
{
|
||||||
|
AZ_TracePrintf("GraphCanvas", AZStd::string::format("Value not found for key: %s", key.c_str()).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslationDatabase::Add(const TranslationFormat& format)
|
bool TranslationDatabase::Add(const TranslationFormat& format)
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ namespace GraphCanvas
|
|||||||
|
|
||||||
bool HasKey(const AZStd::string& key) override;
|
bool HasKey(const AZStd::string& key) override;
|
||||||
|
|
||||||
TranslationRequests::Details GetDetails(const AZStd::string& key) override;
|
TranslationRequests::Details GetDetails(const AZStd::string& key, const Details& value) override;
|
||||||
|
|
||||||
const char* Get(const AZStd::string& key) override;
|
bool Get(const AZStd::string& key, AZStd::string& value) override;
|
||||||
|
|
||||||
bool Add(const TranslationFormat& format) override;
|
bool Add(const TranslationFormat& format) override;
|
||||||
|
|
||||||
|
|||||||
@@ -11,17 +11,6 @@
|
|||||||
|
|
||||||
namespace GraphCanvas
|
namespace GraphCanvas
|
||||||
{
|
{
|
||||||
namespace Schema
|
|
||||||
{
|
|
||||||
namespace Field
|
|
||||||
{
|
|
||||||
static constexpr char key[] = "key";
|
|
||||||
static constexpr char context[] = "context";
|
|
||||||
static constexpr char variant[] = "variant";
|
|
||||||
static constexpr char entries[] = "entries";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AZ_CLASS_ALLOCATOR_IMPL(TranslationFormatSerializer, AZ::SystemAllocator, 0);
|
AZ_CLASS_ALLOCATOR_IMPL(TranslationFormatSerializer, AZ::SystemAllocator, 0);
|
||||||
|
|
||||||
void AddEntryToDatabase(const AZStd::string& baseKey, const AZStd::string& name, const rapidjson::Value& it, TranslationFormat* translationFormat)
|
void AddEntryToDatabase(const AZStd::string& baseKey, const AZStd::string& name, const rapidjson::Value& it, TranslationFormat* translationFormat)
|
||||||
@@ -35,8 +24,10 @@ namespace GraphCanvas
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
AZStd::string existingValue = translationFormat->m_database[finalKey.c_str()];
|
||||||
|
|
||||||
// There is a name collision
|
// There is a name collision
|
||||||
AZStd::string error = AZStd::string::format("Unable to store key: %s with value: %s because that key already exists", finalKey.c_str(), it.GetString());
|
AZStd::string error = AZStd::string::format("Unable to store key: %s with value: %s because that key already exists with value: %s (proposed: %s)", finalKey.c_str(), it.GetString(), existingValue.c_str(), it.GetString());
|
||||||
AZ_Error("TranslationSerializer", false, error.c_str());
|
AZ_Error("TranslationSerializer", false, error.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +65,7 @@ namespace GraphCanvas
|
|||||||
const rapidjson::Value& array = it;
|
const rapidjson::Value& array = it;
|
||||||
for (rapidjson::SizeType i = 0; i < array.Size(); ++i)
|
for (rapidjson::SizeType i = 0; i < array.Size(); ++i)
|
||||||
{
|
{
|
||||||
// so, here, I need to go in and if there is a "key" member within the object, then I need to use that,
|
// if there is a "base" member within the object, then use it, otherwise use the index
|
||||||
// if there isn't, I can use the %d
|
|
||||||
if (array[i].IsObject())
|
if (array[i].IsObject())
|
||||||
{
|
{
|
||||||
if (array[i].HasMember(Schema::Field::key))
|
if (array[i].HasMember(Schema::Field::key))
|
||||||
@@ -156,7 +146,7 @@ namespace GraphCanvas
|
|||||||
AZStd::string baseKey = contextStr;
|
AZStd::string baseKey = contextStr;
|
||||||
if (keyStr.empty())
|
if (keyStr.empty())
|
||||||
{
|
{
|
||||||
AZ_Error("TranslationDatabase", false, "Every entry in the Translation data must have a key: %s", baseKey.c_str());
|
AZ_Warning("TranslationDatabase", false, "Every entry in the Translation data must have a key: %s", baseKey.c_str());
|
||||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Every entry in the Translation data must have a key");
|
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Every entry in the Translation data must have a key");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,4 +23,15 @@ namespace GraphCanvas
|
|||||||
AZ::JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue,
|
AZ::JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue,
|
||||||
const void* defaultValue, const AZ::Uuid& valueTypeId, AZ::JsonSerializerContext& context) override;
|
const void* defaultValue, const AZ::Uuid& valueTypeId, AZ::JsonSerializerContext& context) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Schema
|
||||||
|
{
|
||||||
|
namespace Field
|
||||||
|
{
|
||||||
|
inline constexpr char key[] = "base";
|
||||||
|
inline constexpr char context[] = "context";
|
||||||
|
inline constexpr char variant[] = "variant";
|
||||||
|
inline constexpr char entries[] = "entries";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user